From 70b211e3553c00c571123f124b3a607a389c81f4 Mon Sep 17 00:00:00 2001 From: huangjingquan Date: Thu, 1 Aug 2013 10:33:49 +0800 Subject: [PATCH] first commit --- .gitignore | 20 + .hgignore | 39 + Gemfile | 95 + Gemfile.lock | 155 + README.rdoc | 5 + Rakefile | 7 + app/controllers/account_controller.rb | 307 ++ app/controllers/activities_controller.rb | 87 + app/controllers/admin_controller.rb | 83 + app/controllers/application_controller.rb | 610 +++ app/controllers/attachments_controller.rb | 154 + app/controllers/auth_sources_controller.rb | 96 + app/controllers/auto_completes_controller.rb | 44 + app/controllers/avatar_controller.rb | 78 + app/controllers/bids_controller.rb | 154 + app/controllers/boards_controller.rb | 111 + app/controllers/calendars_controller.rb | 56 + app/controllers/comments_controller.rb | 53 + app/controllers/context_menus_controller.rb | 89 + app/controllers/custom_fields_controller.rb | 81 + app/controllers/documents_controller.rb | 95 + app/controllers/enumerations_controller.rb | 98 + app/controllers/files_controller.rb | 54 + app/controllers/gantts_controller.rb | 48 + app/controllers/groups_controller.rb | 141 + .../issue_categories_controller.rb | 122 + app/controllers/issue_relations_controller.rb | 88 + app/controllers/issue_statuses_controller.rb | 81 + app/controllers/issues_controller.rb | 443 ++ app/controllers/journals_controller.rb | 105 + app/controllers/list_controller.rb | 5 + app/controllers/mail_handler_controller.rb | 40 + app/controllers/members_controller.rb | 125 + app/controllers/messages_controller.rb | 142 + app/controllers/my_controller.rb | 198 + app/controllers/news_controller.rb | 112 + app/controllers/previews_controller.rb | 53 + .../project_enumerations_controller.rb | 42 + app/controllers/projects_controller.rb | 365 ++ app/controllers/queries_controller.rb | 106 + app/controllers/reports_controller.rb | 95 + app/controllers/repositories_controller.rb | 435 ++ app/controllers/roles_controller.rb | 108 + app/controllers/search_controller.rb | 111 + app/controllers/settings_controller.rb | 73 + app/controllers/sys_controller.rb | 84 + app/controllers/tags_controller.rb | 77 + app/controllers/test_controller.rb | 126 + app/controllers/timelog_controller.rb | 314 ++ app/controllers/trackers_controller.rb | 101 + app/controllers/users_controller.rb | 320 ++ app/controllers/versions_controller.rb | 182 + app/controllers/watchers_controller.rb | 109 + app/controllers/welcome_controller.rb | 68 + app/controllers/wiki_controller.rb | 357 ++ app/controllers/wikis_controller.rb | 36 + app/controllers/words_controller.rb | 99 + app/controllers/workflows_controller.rb | 128 + app/helpers/account_helper.rb | 21 + app/helpers/activities_helper.rb | 33 + app/helpers/admin_helper.rb | 27 + app/helpers/application_helper.rb | 1287 +++++ app/helpers/attachments_helper.rb | 47 + app/helpers/auth_sources_helper.rb | 24 + app/helpers/avatar_helper.rb | 52 + app/helpers/bids_helper.rb | 32 + app/helpers/boards_helper.rb | 41 + app/helpers/calendars_helper.rb | 58 + app/helpers/context_menus_helper.rb | 43 + app/helpers/custom_fields_helper.rb | 149 + app/helpers/documents_helper.rb | 21 + app/helpers/enumerations_helper.rb | 21 + app/helpers/gantt_helper.rb | 43 + app/helpers/groups_helper.rb | 42 + app/helpers/issue_categories_helper.rb | 21 + app/helpers/issue_relations_helper.rb | 25 + app/helpers/issue_statuses_helper.rb | 21 + app/helpers/issues_helper.rb | 383 ++ app/helpers/journals_helper.rb | 46 + app/helpers/mail_handler_helper.rb | 21 + app/helpers/members_helper.rb | 35 + app/helpers/messages_helper.rb | 21 + app/helpers/my_helper.rb | 72 + app/helpers/news_helper.rb | 21 + app/helpers/projects_helper.rb | 91 + app/helpers/queries_helper.rb | 223 + app/helpers/reports_helper.rb | 43 + app/helpers/repositories_helper.rb | 297 ++ app/helpers/roles_helper.rb | 21 + app/helpers/routes_helper.rb | 39 + app/helpers/search_helper.rb | 70 + app/helpers/settings_helper.rb | 106 + app/helpers/sort_helper.rb | 243 + app/helpers/test_helper.rb | 31 + app/helpers/timelog_helper.rb | 154 + app/helpers/trackers_helper.rb | 21 + app/helpers/users_helper.rb | 64 + app/helpers/versions_helper.rb | 57 + app/helpers/watchers_helper.rb | 86 + app/helpers/welcome_helper.rb | 21 + app/helpers/wiki_helper.rb | 43 + app/helpers/words_helper.rb | 47 + app/helpers/workflows_helper.rb | 32 + app/models/attachment.rb | 326 ++ app/models/auth_source.rb | 92 + app/models/auth_source_ldap.rb | 200 + app/models/bid.rb | 58 + app/models/biding_project.rb | 44 + app/models/board.rb | 90 + app/models/change.rb | 37 + app/models/changeset.rb | 278 + app/models/comment.rb | 26 + app/models/comment_observer.rb | 24 + app/models/custom_field.rb | 355 ++ app/models/custom_field_value.rb | 50 + app/models/custom_value.rb | 49 + app/models/document.rb | 57 + app/models/document_category.rb | 40 + app/models/document_category_custom_field.rb | 22 + app/models/document_observer.rb | 22 + app/models/enabled_module.rb | 38 + app/models/enumeration.rb | 141 + app/models/group.rb | 90 + app/models/group_custom_field.rb | 22 + app/models/issue.rb | 1443 +++++ app/models/issue_category.rb | 48 + app/models/issue_custom_field.rb | 27 + app/models/issue_observer.rb | 22 + app/models/issue_priority.rb | 68 + app/models/issue_priority_custom_field.rb | 23 + app/models/issue_query.rb | 405 ++ app/models/issue_relation.rb | 182 + app/models/issue_status.rb | 105 + app/models/journal.rb | 132 + app/models/journal_detail.rb | 41 + app/models/journal_observer.rb | 29 + app/models/journals_for_message.rb | 12 + app/models/mail_handler.rb | 490 ++ app/models/mailer.rb | 474 ++ app/models/member.rb | 113 + app/models/member_role.rb | 71 + app/models/message.rb | 108 + app/models/message_observer.rb | 22 + app/models/messages_for_bids.rb | 3 + app/models/messages_for_user.rb | 50 + app/models/news.rb | 66 + app/models/news_observer.rb | 22 + app/models/principal.rb | 112 + app/models/project.rb | 1040 ++++ app/models/project_custom_field.rb | 22 + app/models/project_tags.rb | 45 + app/models/query.rb | 828 +++ app/models/repository.rb | 438 ++ app/models/repository/bazaar.rb | 128 + app/models/repository/cvs.rb | 208 + app/models/repository/darcs.rb | 114 + app/models/repository/filesystem.rb | 50 + app/models/repository/git.rb | 268 + app/models/repository/mercurial.rb | 159 + app/models/repository/subversion.rb | 116 + app/models/role.rb | 208 + app/models/setting.rb | 178 + app/models/tag.rb | 19 + app/models/time_entry.rb | 119 + app/models/time_entry_activity.rb | 34 + .../time_entry_activity_custom_field.rb | 22 + app/models/time_entry_custom_field.rb | 23 + app/models/time_entry_query.rb | 115 + app/models/token.rb | 83 + app/models/tracker.rb | 115 + app/models/user.rb | 737 +++ app/models/user_custom_field.rb | 23 + app/models/user_extension.rb | 11 + app/models/user_preference.rb | 59 + app/models/version.rb | 289 + app/models/version_custom_field.rb | 22 + app/models/watcher.rb | 66 + app/models/watchers_of_projects.rb | 46 + app/models/watchers_of_user.rb | 65 + app/models/wiki.rb | 97 + app/models/wiki_content.rb | 148 + app/models/wiki_content_observer.rb | 28 + app/models/wiki_page.rb | 251 + app/models/wiki_redirect.rb | 23 + app/models/workflow_permission.rb | 45 + app/models/workflow_rule.rb | 73 + app/models/workflow_transition.rb | 39 + app/sweepers/NOTEMPTY | 0 app/views/account/login.html.erb | 47 + app/views/account/logout.html.erb | 3 + app/views/account/lost_password.html.erb | 11 + app/views/account/password_recovery.html.erb | 20 + app/views/account/register.html.erb | 31 + app/views/activities/index.html.erb | 142 + app/views/admin/_menu.html.erb | 3 + app/views/admin/_no_data.html.erb | 8 + app/views/admin/index.html.erb | 8 + app/views/admin/info.html.erb | 19 + app/views/admin/plugins.html.erb | 19 + app/views/admin/projects.html.erb | 45 + app/views/attachments/_form.html.erb | 31 + app/views/attachments/_links.html.erb | 33 + app/views/attachments/destroy.js.erb | 1 + app/views/attachments/diff.html.erb | 22 + app/views/attachments/file.html.erb | 17 + app/views/attachments/show.api.rsb | 1 + app/views/attachments/upload.api.rsb | 3 + app/views/attachments/upload.js.erb | 9 + app/views/auth_sources/_form.html.erb | 6 + .../_form_auth_source_ldap.html.erb | 24 + app/views/auth_sources/edit.html.erb | 6 + app/views/auth_sources/index.html.erb | 31 + app/views/auth_sources/new.html.erb | 7 + app/views/auto_completes/issues.html.erb | 7 + app/views/avatar/_avatar_form.html.erb | 27 + app/views/avatar/upload.js.erb | 4 + app/views/bids/_history.html.erb | 37 + app/views/bids/_new.html.erb | 13 + app/views/bids/_project_list.html.erb | 35 + app/views/bids/add.js.erb | 4 + app/views/bids/back.js.erb | 1 + app/views/bids/create.js.erb | 2 + app/views/bids/destroy.js.erb | 1 + app/views/bids/index.html.erb | 37 + app/views/bids/more.js.erb | 1 + app/views/bids/new.js.erb | 2 + app/views/bids/new_bid.html.erb | 14 + app/views/bids/show.html.erb | 17 + app/views/bids/show_project.html.erb | 32 + app/views/boards/_form.html.erb | 9 + app/views/boards/edit.html.erb | 6 + app/views/boards/index.html.erb | 38 + app/views/boards/new.html.erb | 6 + app/views/boards/show.html.erb | 66 + app/views/calendars/show.html.erb | 43 + app/views/common/_calendar.html.erb | 32 + app/views/common/_diff.html.erb | 68 + app/views/common/_file.html.erb | 18 + app/views/common/_preview.html.erb | 3 + app/views/common/_project.html.erb | 58 + app/views/common/_tabs.html.erb | 28 + app/views/common/error.html.erb | 8 + app/views/common/error_messages.api.rsb | 5 + app/views/common/feed.atom.builder | 31 + app/views/context_menus/issues.html.erb | 139 + app/views/context_menus/time_entries.html.erb | 33 + app/views/custom_fields/_form.html.erb | 99 + app/views/custom_fields/_index.html.erb | 32 + app/views/custom_fields/edit.html.erb | 8 + app/views/custom_fields/index.html.erb | 5 + app/views/custom_fields/new.html.erb | 19 + app/views/custom_fields/new.js.erb | 1 + app/views/documents/_document.html.erb | 6 + app/views/documents/_form.html.erb | 15 + app/views/documents/edit.html.erb | 8 + app/views/documents/index.html.erb | 34 + app/views/documents/new.html.erb | 6 + app/views/documents/show.html.erb | 32 + app/views/enumerations/_form.html.erb | 11 + app/views/enumerations/destroy.html.erb | 12 + app/views/enumerations/edit.html.erb | 6 + app/views/enumerations/index.api.rsb | 9 + app/views/enumerations/index.html.erb | 34 + app/views/enumerations/new.html.erb | 7 + app/views/files/index.html.erb | 46 + app/views/files/new.html.erb | 16 + app/views/gantts/show.html.erb | 319 ++ app/views/groups/_form.html.erb | 8 + app/views/groups/_general.html.erb | 4 + app/views/groups/_memberships.html.erb | 65 + app/views/groups/_users.html.erb | 39 + app/views/groups/add_users.js.erb | 4 + app/views/groups/autocomplete_for_user.js.erb | 1 + app/views/groups/destroy_membership.js.erb | 1 + app/views/groups/edit.html.erb | 5 + app/views/groups/edit_membership.js.erb | 6 + app/views/groups/index.api.rsb | 10 + app/views/groups/index.html.erb | 26 + app/views/groups/new.html.erb | 9 + app/views/groups/remove_user.js.erb | 1 + app/views/groups/show.api.rsb | 30 + app/views/groups/show.html.erb | 7 + app/views/issue_categories/_form.html.erb | 6 + .../issue_categories/_new_modal.html.erb | 9 + app/views/issue_categories/create.js.erb | 3 + app/views/issue_categories/destroy.html.erb | 16 + app/views/issue_categories/edit.html.erb | 7 + app/views/issue_categories/index.api.rsb | 10 + app/views/issue_categories/new.html.erb | 7 + app/views/issue_categories/new.js.erb | 2 + app/views/issue_categories/show.api.rsb | 6 + app/views/issue_relations/_form.html.erb | 14 + app/views/issue_relations/create.js.erb | 6 + app/views/issue_relations/destroy.js.erb | 1 + app/views/issue_relations/index.api.rsb | 11 + app/views/issue_relations/show.api.rsb | 7 + app/views/issue_statuses/_form.html.erb | 12 + app/views/issue_statuses/edit.html.erb | 6 + app/views/issue_statuses/index.api.rsb | 10 + app/views/issue_statuses/index.html.erb | 39 + app/views/issue_statuses/new.html.erb | 6 + app/views/issues/_action_menu.html.erb | 7 + app/views/issues/_attributes.html.erb | 73 + app/views/issues/_changesets.html.erb | 10 + app/views/issues/_conflict.html.erb | 26 + app/views/issues/_edit.html.erb | 51 + app/views/issues/_form.html.erb | 45 + app/views/issues/_form_custom_fields.html.erb | 13 + app/views/issues/_history.html.erb | 22 + app/views/issues/_list.html.erb | 108 + app/views/issues/_list_simple.html.erb | 29 + app/views/issues/_relations.html.erb | 44 + app/views/issues/_sidebar.html.erb | 17 + app/views/issues/bulk_edit.html.erb | 150 + app/views/issues/bulk_edit.js.erb | 1 + app/views/issues/destroy.html.erb | 15 + app/views/issues/edit.html.erb | 6 + app/views/issues/index.api.rsb | 35 + app/views/issues/index.html.erb | 121 + app/views/issues/new.html.erb | 53 + app/views/issues/show.api.rsb | 74 + app/views/issues/show.html.erb | 164 + app/views/issues/update_form.js.erb | 7 + app/views/journals/_notes_form.html.erb | 18 + app/views/journals/diff.html.erb | 10 + app/views/journals/edit.js.erb | 8 + app/views/journals/index.builder | 30 + app/views/journals/new.js.erb | 10 + app/views/journals/update.js.erb | 9 + app/views/layouts/_base_header.html.erb | 7 + app/views/layouts/_tag.html.erb | 20 + app/views/layouts/_tag_name.html.erb | 55 + app/views/layouts/admin.html.erb | 8 + app/views/layouts/base.html.erb | 43 + app/views/layouts/base.html_old.erb | 80 + app/views/layouts/base_.html.erb | 75 + app/views/layouts/base_bids.html.erb | 159 + app/views/layouts/base_old.html.erb | 156 + app/views/layouts/base_projects.html.erb | 135 + app/views/layouts/base_users.html.erb | 155 + app/views/layouts/mailer.html.erb | 33 + app/views/layouts/mailer.text.erb | 4 + app/views/list/members.html.erb | 8 + app/views/mailer/_issue.html.erb | 15 + app/views/mailer/_issue.text.erb | 13 + app/views/mailer/account_activated.html.erb | 2 + app/views/mailer/account_activated.text.erb | 2 + .../account_activation_request.html.erb | 2 + .../account_activation_request.text.erb | 2 + app/views/mailer/account_information.html.erb | 11 + app/views/mailer/account_information.text.erb | 6 + app/views/mailer/attachments_added.html.erb | 5 + app/views/mailer/attachments_added.text.erb | 4 + app/views/mailer/document_added.html.erb | 3 + app/views/mailer/document_added.text.erb | 4 + app/views/mailer/issue_add.html.erb | 3 + app/views/mailer/issue_add.text.erb | 4 + app/views/mailer/issue_edit.html.erb | 11 + app/views/mailer/issue_edit.text.erb | 12 + app/views/mailer/lost_password.html.erb | 4 + app/views/mailer/lost_password.text.erb | 4 + app/views/mailer/message_posted.html.erb | 4 + app/views/mailer/message_posted.text.erb | 4 + app/views/mailer/news_added.html.erb | 4 + app/views/mailer/news_added.text.erb | 5 + app/views/mailer/news_comment_added.html.erb | 5 + app/views/mailer/news_comment_added.text.erb | 6 + app/views/mailer/register.html.erb | 2 + app/views/mailer/register.text.erb | 2 + app/views/mailer/reminder.html.erb | 9 + app/views/mailer/reminder.text.erb | 7 + app/views/mailer/test_email.html.erb | 2 + app/views/mailer/test_email.text.erb | 2 + app/views/mailer/wiki_content_added.html.erb | 3 + app/views/mailer/wiki_content_added.text.erb | 5 + .../mailer/wiki_content_updated.html.erb | 6 + .../mailer/wiki_content_updated.text.erb | 8 + app/views/members/autocomplete.js.erb | 1 + app/views/members/create.js.erb | 11 + app/views/members/destroy.js.erb | 2 + app/views/members/index.api.rsb | 18 + app/views/members/show.api.rsb | 14 + app/views/members/update.js.erb | 3 + app/views/messages/_form.html.erb | 32 + app/views/messages/edit.html.erb | 17 + app/views/messages/new.html.erb | 9 + app/views/messages/quote.js.erb | 4 + app/views/messages/show.html.erb | 86 + app/views/my/_block.html.erb | 10 + app/views/my/_sidebar.html.erb | 36 + app/views/my/account.html.erb | 75 + app/views/my/blocks/_calendar.html.erb | 6 + app/views/my/blocks/_documents.html.erb | 3 + .../my/blocks/_issuesassignedtome.html.erb | 18 + .../my/blocks/_issuesreportedbyme.html.erb | 19 + app/views/my/blocks/_issueswatched.html.erb | 11 + app/views/my/blocks/_news.html.erb | 3 + app/views/my/blocks/_timelog.html.erb | 49 + app/views/my/destroy.html.erb | 11 + app/views/my/page.html.erb | 36 + app/views/my/page_layout.html.erb | 41 + app/views/my/password.html.erb | 23 + app/views/news/_form.html.erb | 10 + app/views/news/_news.html.erb | 27 + app/views/news/edit.html.erb | 12 + app/views/news/index.api.rsb | 14 + app/views/news/index.html.erb | 78 + app/views/news/new.html.erb | 9 + app/views/news/show.html.erb | 78 + app/views/newsold/_form.html.erb | 10 + app/views/newsold/_news.html.erb | 6 + app/views/newsold/edit.html.erb | 12 + app/views/newsold/index.api.rsb | 14 + app/views/newsold/index.html.erb | 46 + app/views/newsold/new.html.erb | 9 + app/views/newsold/show.html.erb | 62 + app/views/previews/issue.html.erb | 11 + app/views/projects/Copy of show.html.erb | 53 + app/views/projects/_edit.html.erb | 4 + app/views/projects/_form.html.erb | 90 + app/views/projects/_members_box.html.erb | 8 + app/views/projects/_project.html.erb | 58 + app/views/projects/copy.html.erb | 20 + app/views/projects/destroy.html.erb | 17 + app/views/projects/file.html.erb | 1 + app/views/projects/focus.html.erb | 1 + app/views/projects/index.api.rsb | 16 + app/views/projects/index.html.erb | 35 + app/views/projects/investor.html.erb | 1 + app/views/projects/issue.html.erb | 1 + app/views/projects/list_members.html.erb | 13 + app/views/projects/member.html.erb | 27 + app/views/projects/mission.html.erb | 1 + app/views/projects/new.html.erb | 8 + app/views/projects/on.html.erb | 1 + app/views/projects/settings.html.erb | 5 + .../projects/settings/_activities.html.erb | 42 + app/views/projects/settings/_boards.html.erb | 36 + .../settings/_issue_categories.html.erb | 29 + app/views/projects/settings/_members.html.erb | 77 + app/views/projects/settings/_modules.html.erb | 18 + .../projects/settings/_repositories.html.erb | 41 + .../projects/settings/_versions.html.erb | 41 + app/views/projects/settings/_wiki.html.erb | 19 + app/views/projects/show-old.html.erb | 97 + app/views/projects/show.api.rsb | 25 + app/views/projects/show.html.erb | 97 + app/views/projects/show_new.html.erb | 97 + app/views/queries/_columns.html.erb | 34 + app/views/queries/_filters.html.erb | 28 + app/views/queries/_form.html.erb | 55 + app/views/queries/edit.html.erb | 6 + app/views/queries/index.api.rsb | 10 + app/views/queries/index.html.erb | 27 + app/views/queries/new.html.erb | 6 + app/views/reports/_details.html.erb | 30 + app/views/reports/_simple.html.erb | 23 + app/views/reports/issue_report.html.erb | 33 + .../reports/issue_report_details.html.erb | 7 + app/views/repositories/_breadcrumbs.html.erb | 31 + app/views/repositories/_dir_list.html.erb | 19 + .../repositories/_dir_list_content.html.erb | 31 + app/views/repositories/_form.html.erb | 27 + .../repositories/_link_to_functions.html.erb | 19 + app/views/repositories/_navigation.html.erb | 34 + .../repositories/_related_issues.html.erb | 40 + .../repositories/_revision_graph.html.erb | 18 + app/views/repositories/_revisions.html.erb | 51 + .../repositories/add_related_issue.js.erb | 7 + app/views/repositories/annotate.html.erb | 36 + app/views/repositories/changes.html.erb | 20 + app/views/repositories/committers.html.erb | 42 + app/views/repositories/diff.html.erb | 27 + app/views/repositories/edit.html.erb | 5 + app/views/repositories/entry.html.erb | 15 + app/views/repositories/new.html.erb | 5 + app/views/repositories/new.js.erb | 1 + .../repositories/remove_related_issue.js.erb | 1 + app/views/repositories/revision.html.erb | 97 + app/views/repositories/revisions.html.erb | 34 + app/views/repositories/show.html.erb | 77 + app/views/repositories/stats.html.erb | 12 + app/views/roles/_form.html.erb | 32 + app/views/roles/edit.html.erb | 6 + app/views/roles/index.api.rsb | 8 + app/views/roles/index.html.erb | 34 + app/views/roles/new.html.erb | 6 + app/views/roles/permissions.html.erb | 55 + app/views/roles/show.api.rsb | 9 + app/views/search/index.html.erb | 52 + app/views/settings/_authentication.html.erb | 38 + app/views/settings/_display.html.erb | 26 + app/views/settings/_general.html.erb | 40 + app/views/settings/_issues.html.erb | 31 + app/views/settings/_mail_handler.html.erb | 23 + app/views/settings/_notifications.html.erb | 42 + app/views/settings/_projects.html.erb | 20 + app/views/settings/_repositories.html.erb | 94 + app/views/settings/edit.html.erb | 5 + app/views/settings/plugin.html.erb | 10 + app/views/tags/_related_tags.html.erb | 14 + app/views/tags/_selected_tags.html.erb | 15 + app/views/tags/_show_results.html.erb | 0 app/views/tags/_tag_search_results.html.erb | 37 + app/views/tags/add_tag.js.erb | 9 + app/views/tags/delete_tag.js.erb | 8 + app/views/tags/index.html.erb | 31 + app/views/test/_message.html.erb | 9 + app/views/test/_new.html.erb | 16 + app/views/test/create.js.erb | 1 + app/views/test/destroy.js.erb | 1 + app/views/test/index.html.erb | 3 + app/views/test/new.js.erb | 3 + app/views/timelog/_date_range.html.erb | 34 + app/views/timelog/_form.html.erb | 32 + app/views/timelog/_list.html.erb | 41 + app/views/timelog/_report_criteria.html.erb | 19 + app/views/timelog/bulk_edit.html.erb | 50 + app/views/timelog/edit.html.erb | 6 + app/views/timelog/index.api.rsb | 18 + app/views/timelog/index.html.erb | 48 + app/views/timelog/new.html.erb | 8 + app/views/timelog/report.html.erb | 74 + app/views/timelog/show.api.rsb | 14 + app/views/trackers/_form.html.erb | 52 + app/views/trackers/edit.html.erb | 5 + app/views/trackers/fields.html.erb | 77 + app/views/trackers/index.api.rsb | 8 + app/views/trackers/index.html.erb | 39 + app/views/trackers/new.html.erb | 5 + app/views/users/_form.html.erb | 51 + app/views/users/_general.html.erb | 7 + app/views/users/_groups.html.erb | 9 + app/views/users/_leave_message.html.erb | 27 + app/views/users/_mail_notifications.html.erb | 27 + app/views/users/_memberships.html.erb | 67 + app/views/users/_preferences.html.erb | 6 + app/views/users/blocks/_calendar.html.erb | 6 + .../users/blocks/_issuesassignedtome.html.erb | 18 + app/views/users/destroy_membership.js.erb | 1 + app/views/users/edit.html.erb | 11 + app/views/users/edit_membership.js.erb | 6 + app/views/users/index.api.rsb | 15 + app/views/users/index.html.erb | 155 + app/views/users/leave_message.js.erb | 3 + app/views/users/list.api.rsb | 15 + app/views/users/list.html.erb | 81 + app/views/users/new.html.erb | 30 + app/views/users/show.api.rsb | 36 + app/views/users/show.html.erb | 26 + app/views/users/show_old.html.erb | 343 ++ app/views/users/tag_save.js.erb | 4 + app/views/users/user_activities.html.erb | 45 + app/views/users/user_comments.html.erb | 0 app/views/users/user_newfeedback.html.erb | 8 + app/views/users/user_projects.html.erb | 39 + app/views/versions/_form.html.erb | 16 + app/views/versions/_issue_counts.html.erb | 33 + app/views/versions/_new_modal.html.erb | 9 + app/views/versions/_overview.html.erb | 32 + app/views/versions/create.js.erb | 3 + app/views/versions/edit.html.erb | 7 + app/views/versions/index.api.rsb | 19 + app/views/versions/index.html.erb | 68 + app/views/versions/new.html.erb | 6 + app/views/versions/new.js.erb | 2 + app/views/versions/show.api.rsb | 15 + app/views/versions/show.html.erb | 55 + app/views/versions/status_by.js.erb | 1 + app/views/watchers/_new.html.erb | 27 + app/views/watchers/_set_watcher.js.erb | 2 + app/views/watchers/_watchers.html.erb | 12 + app/views/watchers/append.js.erb | 4 + .../watchers/autocomplete_for_user.html.erb | 1 + app/views/watchers/create.js.erb | 2 + app/views/watchers/destroy.js.erb | 1 + app/views/watchers/new.js.erb | 3 + app/views/welcome/index.html.erb | 69 + app/views/welcome/robots.html.erb | 10 + app/views/wiki/_content.html.erb | 4 + app/views/wiki/_sidebar.html.erb | 9 + app/views/wiki/annotate.html.erb | 41 + app/views/wiki/date_index.html.erb | 36 + app/views/wiki/destroy.html.erb | 22 + app/views/wiki/diff.html.erb | 27 + app/views/wiki/edit.html.erb | 46 + app/views/wiki/export.html.erb | 21 + app/views/wiki/export_multiple.html.erb | 34 + app/views/wiki/history.html.erb | 42 + app/views/wiki/index.api.rsb | 13 + app/views/wiki/index.html.erb | 35 + app/views/wiki/rename.html.erb | 21 + app/views/wiki/show.api.rsb | 18 + app/views/wiki/show.html.erb | 71 + app/views/wikis/destroy.html.erb | 10 + app/views/wikis/edit.js.erb | 1 + app/views/words/_message.html.erb | 26 + app/views/words/_new.html.erb | 13 + app/views/words/back.js.erb | 1 + app/views/words/create.js.erb | 2 + app/views/words/destroy.js.erb | 1 + app/views/words/more.js.erb | 1 + app/views/words/new.js.erb | 2 + app/views/workflows/_action_menu.html.erb | 5 + app/views/workflows/_form.html.erb | 41 + app/views/workflows/copy.html.erb | 40 + app/views/workflows/edit.html.erb | 58 + app/views/workflows/index.html.erb | 35 + app/views/workflows/permissions.html.erb | 95 + config.ru | 4 + config/additional_environment.rb | 10 + config/additional_environment.rb.example | 10 + config/application.rb | 62 + config/boot.rb | 6 + config/configuration.yml | 206 + config/configuration.yml.example | 206 + config/database.yml | 45 + config/database.yml.example | 52 + config/environment.rb | 14 + config/environments/development.rb | 19 + config/environments/production.rb | 32 + config/environments/test.rb | 30 + config/environments/test_pgsql.rb | 1 + config/environments/test_sqlite3.rb | 1 + config/initializers/00-core_plugins.rb | 15 + config/initializers/10-patches.rb | 167 + config/initializers/20-mime_types.rb | 4 + config/initializers/30-redmine.rb | 15 + config/initializers/backtrace_silencers.rb | 7 + config/initializers/inflections.rb | 10 + config/initializers/secret_token.rb | 11 + config/locales/ar.yml | 1089 ++++ config/locales/az.yml | 1186 +++++ config/locales/bg.yml | 1086 ++++ config/locales/bs.yml | 1102 ++++ config/locales/ca.yml | 1091 ++++ config/locales/cs.yml | 1093 ++++ config/locales/da.yml | 1106 ++++ config/locales/de.yml | 1101 ++++ config/locales/el.yml | 1089 ++++ config/locales/en-GB.yml | 1091 ++++ config/locales/en.yml | 1084 ++++ config/locales/es.yml | 1125 ++++ config/locales/et.yml | 1102 ++++ config/locales/eu.yml | 1090 ++++ config/locales/fa.yml | 1091 ++++ config/locales/fi.yml | 1110 ++++ config/locales/fr.yml | 1102 ++++ config/locales/gl.yml | 1100 ++++ config/locales/he.yml | 1094 ++++ config/locales/hr.yml | 1090 ++++ config/locales/hu.yml | 1108 ++++ config/locales/id.yml | 1093 ++++ config/locales/it.yml | 1090 ++++ config/locales/ja.yml | 1118 ++++ config/locales/ko.yml | 1138 ++++ config/locales/lt.yml | 1149 ++++ config/locales/lv.yml | 1083 ++++ config/locales/mk.yml | 1089 ++++ config/locales/mn.yml | 1090 ++++ config/locales/nl.yml | 1070 ++++ config/locales/no.yml | 1079 ++++ config/locales/pl.yml | 1110 ++++ config/locales/pt-BR.yml | 1109 ++++ config/locales/pt.yml | 1095 ++++ config/locales/ro.yml | 1084 ++++ config/locales/ru.yml | 1199 +++++ config/locales/sk.yml | 1086 ++++ config/locales/sl.yml | 1089 ++++ config/locales/sq.yml | 1085 ++++ config/locales/sr-YU.yml | 1091 ++++ config/locales/sr.yml | 1090 ++++ config/locales/sv.yml | 1127 ++++ config/locales/th.yml | 1086 ++++ config/locales/tr.yml | 1108 ++++ config/locales/uk.yml | 1084 ++++ config/locales/vi.yml | 1142 ++++ config/locales/zh-TW.yml | 1171 +++++ config/locales/zh.yml | 1149 ++++ config/preinitializer.rb | 20 + config/routes.rb | 425 ++ config/settings.yml | 238 + db/development.sqlite3 | 0 db/migrate/001_setup.rb | 323 ++ db/migrate/002_issue_move.rb | 12 + db/migrate/003_issue_add_note.rb | 12 + db/migrate/004_export_pdf.rb | 14 + db/migrate/005_issue_start_date.rb | 11 + db/migrate/006_calendar_and_activity.rb | 16 + db/migrate/007_create_journals.rb | 56 + db/migrate/008_create_user_preferences.rb | 12 + db/migrate/009_add_hide_mail_pref.rb | 9 + db/migrate/010_create_comments.rb | 16 + db/migrate/011_add_news_comments_count.rb | 9 + db/migrate/012_add_comments_permissions.rb | 14 + db/migrate/013_create_queries.rb | 15 + db/migrate/014_add_queries_permissions.rb | 12 + db/migrate/015_create_repositories.rb | 12 + .../016_add_repositories_permissions.rb | 22 + db/migrate/017_create_settings.rb | 12 + .../018_set_doc_and_files_notifications.rb | 18 + db/migrate/019_add_issue_status_position.rb | 10 + db/migrate/020_add_role_position.rb | 10 + db/migrate/021_add_tracker_position.rb | 10 + db/migrate/022_serialize_possibles_values.rb | 13 + db/migrate/023_add_tracker_is_in_roadmap.rb | 9 + db/migrate/024_add_roadmap_permission.rb | 12 + db/migrate/025_add_search_permission.rb | 12 + .../026_add_repository_login_and_password.rb | 11 + db/migrate/027_create_wikis.rb | 14 + db/migrate/028_create_wiki_pages.rb | 14 + db/migrate/029_create_wiki_contents.rb | 30 + .../030_add_projects_feeds_permissions.rb | 12 + db/migrate/031_add_repository_root_url.rb | 9 + db/migrate/032_create_time_entries.rb | 24 + db/migrate/033_add_timelog_permissions.rb | 12 + db/migrate/034_create_changesets.rb | 16 + db/migrate/035_create_changes.rb | 16 + db/migrate/036_add_changeset_commit_date.rb | 10 + db/migrate/037_add_project_identifier.rb | 9 + db/migrate/038_add_custom_field_is_filter.rb | 9 + db/migrate/039_create_watchers.rb | 13 + db/migrate/040_create_changesets_issues.rb | 13 + db/migrate/041_rename_comment_to_comments.rb | 13 + db/migrate/042_create_issue_relations.rb | 14 + db/migrate/043_add_relations_permissions.rb | 14 + db/migrate/044_set_language_length_to_five.rb | 9 + db/migrate/045_create_boards.rb | 18 + db/migrate/046_create_messages.rb | 21 + db/migrate/047_add_boards_permissions.rb | 16 + .../048_allow_null_version_effective_date.rb | 9 + .../049_add_wiki_destroy_page_permission.rb | 12 + .../050_add_wiki_attachments_permissions.rb | 14 + db/migrate/051_add_project_status.rb | 9 + db/migrate/052_add_changes_revision.rb | 9 + db/migrate/053_add_changes_branch.rb | 9 + db/migrate/054_add_changesets_scmid.rb | 9 + db/migrate/055_add_repositories_type.rb | 11 + ...056_add_repositories_changes_permission.rb | 12 + .../057_add_versions_wiki_page_title.rb | 9 + ...058_add_issue_categories_assigned_to_id.rb | 9 + db/migrate/059_add_roles_assignable.rb | 9 + .../060_change_changesets_committer_limit.rb | 9 + db/migrate/061_add_roles_builtin.rb | 9 + db/migrate/062_insert_builtin_roles.rb | 16 + db/migrate/063_add_roles_permissions.rb | 9 + db/migrate/064_drop_permissions.rb | 10 + db/migrate/065_add_settings_updated_on.rb | 11 + .../066_add_custom_value_customized_index.rb | 9 + db/migrate/067_create_wiki_redirects.rb | 15 + db/migrate/068_create_enabled_modules.rb | 18 + db/migrate/069_add_issues_estimated_hours.rb | 9 + ...0_change_attachments_content_type_limit.rb | 9 + db/migrate/071_add_queries_column_names.rb | 9 + db/migrate/072_add_enumerations_position.rb | 15 + db/migrate/073_add_enumerations_is_default.rb | 9 + db/migrate/074_add_auth_sources_tls.rb | 9 + .../075_add_members_mail_notification.rb | 9 + db/migrate/076_allow_null_position.rb | 14 + .../077_remove_issue_statuses_html_color.rb | 9 + db/migrate/078_add_custom_fields_position.rb | 15 + .../079_add_user_preferences_time_zone.rb | 9 + db/migrate/080_add_users_type.rb | 10 + db/migrate/081_create_projects_trackers.rb | 19 + db/migrate/082_add_messages_locked.rb | 9 + db/migrate/083_add_messages_sticky.rb | 9 + .../084_change_auth_sources_account_limit.rb | 9 + ...e_tracker_old_status_index_to_workflows.rb | 9 + .../086_add_custom_fields_searchable.rb | 9 + ...087_change_projects_description_to_text.rb | 8 + .../088_add_custom_fields_default_value.rb | 9 + db/migrate/089_add_attachments_description.rb | 9 + db/migrate/090_change_versions_name_limit.rb | 9 + ...91_change_changesets_revision_to_string.rb | 32 + ..._change_changes_from_revision_to_string.rb | 9 + db/migrate/093_add_wiki_pages_protected.rb | 9 + .../094_change_projects_homepage_limit.rb | 9 + db/migrate/095_add_wiki_pages_parent_id.rb | 9 + .../096_add_commit_access_permission.rb | 13 + .../097_add_view_wiki_edits_permission.rb | 13 + .../098_set_topic_authors_as_watchers.rb | 15 + ...elete_wiki_pages_attachments_permission.rb | 13 + db/migrate/100_add_changesets_user_id.rb | 9 + db/migrate/101_populate_changesets_user_id.rb | 18 + db/migrate/102_add_custom_fields_editable.rb | 9 + db/migrate/103_set_custom_fields_editable.rb | 9 + db/migrate/104_add_projects_lft_and_rgt.rb | 11 + db/migrate/105_build_projects_tree.rb | 8 + .../106_remove_projects_projects_count.rb | 9 + .../107_add_open_id_authentication_tables.rb | 20 + db/migrate/108_add_identity_url_to_users.rb | 9 + ...4190337_add_watchers_user_id_type_index.rb | 9 + ...0090312172426_add_queries_sort_criteria.rb | 9 + ...4159_add_projects_trackers_unique_index.rb | 21 + .../20090318181151_extend_settings_name.rb | 9 + ...20090323224724_add_type_to_enumerations.rb | 9 + ...090401221305_update_enumerations_to_sti.rb | 11 + ...231134_add_active_field_to_enumerations.rb | 9 + ...90403001910_add_project_to_enumerations.rb | 11 + ...406161854_add_parent_id_to_enumerations.rb | 9 + .../20090425161243_add_queries_group_by.rb | 9 + .../20090503121501_create_member_roles.rb | 12 + .../20090503121505_populate_member_roles.rb | 12 + .../20090503121510_drop_members_role_id.rb | 9 + ...20090614091200_fix_messages_sticky_null.rb | 9 + .../20090704172350_populate_users_type.rb | 8 + .../20090704172355_create_groups_users.rb | 13 + ...4172358_add_member_roles_inherited_from.rb | 9 + .../20091010093521_fix_users_custom_values.rb | 9 + ...212227_add_missing_indexes_to_workflows.rb | 13 + ...ssing_indexes_to_custom_fields_projects.rb | 9 + ...7212644_add_missing_indexes_to_messages.rb | 11 + ...938_add_missing_indexes_to_repositories.rb | 9 + ...7213027_add_missing_indexes_to_comments.rb | 11 + ...113_add_missing_indexes_to_enumerations.rb | 9 + ...13151_add_missing_indexes_to_wiki_pages.rb | 11 + ...7213228_add_missing_indexes_to_watchers.rb | 11 + ...257_add_missing_indexes_to_auth_sources.rb | 9 + ...213332_add_missing_indexes_to_documents.rb | 9 + ...017213444_add_missing_indexes_to_tokens.rb | 9 + ...13536_add_missing_indexes_to_changesets.rb | 11 + ...add_missing_indexes_to_issue_categories.rb | 9 + ...716_add_missing_indexes_to_member_roles.rb | 11 + ...017213757_add_missing_indexes_to_boards.rb | 9 + ...add_missing_indexes_to_user_preferences.rb | 9 + ...017213910_add_missing_indexes_to_issues.rb | 21 + ...17214015_add_missing_indexes_to_members.rb | 11 + ...07_add_missing_indexes_to_custom_fields.rb | 9 + ...17214136_add_missing_indexes_to_queries.rb | 11 + ...236_add_missing_indexes_to_time_entries.rb | 11 + ...91017214308_add_missing_indexes_to_news.rb | 9 + ...1017214336_add_missing_indexes_to_users.rb | 11 + ...4406_add_missing_indexes_to_attachments.rb | 11 + ...40_add_missing_indexes_to_wiki_contents.rb | 9 + ...19_add_missing_indexes_to_custom_values.rb | 9 + ...7214611_add_missing_indexes_to_journals.rb | 11 + ..._add_missing_indexes_to_issue_relations.rb | 11 + ...0_add_missing_indexes_to_wiki_redirects.rb | 9 + ...ssing_indexes_to_custom_fields_trackers.rb | 9 + .../20091025163651_add_activity_indexes.rb | 25 + .../20091108092559_add_versions_status.rb | 10 + ...091114105931_add_view_issues_permission.rb | 13 + ..._add_default_done_ratio_to_issue_status.rb | 9 + .../20091205124427_add_versions_sharing.rb | 10 + ...509_add_lft_and_rgt_indexes_to_projects.rb | 11 + ...091220183727_add_index_to_settings_name.rb | 9 + ...91220184736_add_indexes_to_issue_status.rb | 13 + .../20091225164732_remove_enumerations_opt.rb | 12 + ...7112908_change_wiki_contents_text_limit.rb | 16 + ...hange_users_mail_notification_to_string.rb | 17 + ...9193813_update_mail_notification_values.rb | 11 + ...221100219_add_index_on_changesets_scmid.rb | 9 + ...13132032_add_issues_nested_sets_columns.rb | 17 + ...13171051_add_index_on_issues_nested_set.rb | 9 + ...164950_change_changes_path_length_limit.rb | 14 + ...dar_and_gantt_modules_where_appropriate.rb | 12 + ...01104182107_add_unique_index_on_members.rb | 22 + ...0101107130441_add_custom_fields_visible.rb | 10 + ...101114115114_change_projects_name_limit.rb | 9 + ...115359_change_projects_identifier_limit.rb | 9 + ...60626_add_workflows_assignee_and_author.rb | 14 + db/migrate/20110223180944_add_users_salt.rb | 9 + .../20110223180953_salt_user_passwords.rb | 13 + ...24000000_add_repositories_path_encoding.rb | 9 + ...0112_change_repositories_password_limit.rb | 9 + ...nge_auth_sources_account_password_limit.rb | 9 + ...0_change_journal_details_values_to_text.rb | 11 + ...228000000_add_repositories_log_encoding.rb | 9 + ...28000100_copy_repositories_log_encoding.rb | 11 + .../20110401192910_add_index_to_users_type.rb | 9 + ...10408103312_add_roles_issues_visibility.rb | 9 + .../20110412065600_add_issues_is_private.rb | 9 + ...10511000000_add_repositories_extra_info.rb | 9 + ...20110902000000_create_changeset_parents.rb | 14 + ...315_add_unique_index_to_issue_relations.rb | 16 + ...20115143024_add_repositories_identifier.rb | 9 + ...20115143100_add_repositories_is_default.rb | 9 + ...20120115143126_set_default_repositories.rb | 14 + ...120127174243_add_custom_fields_multiple.rb | 9 + ...20120205111326_change_users_login_limit.rb | 9 + ...9_change_attachments_container_defaults.rb | 25 + .../20120301153455_add_auth_sources_filter.rb | 9 + ...2150750_change_repositories_to_full_sti.rb | 17 + ...20120705074331_add_trackers_fields_bits.rb | 9 + ...20120707064544_add_auth_sources_timeout.rb | 9 + .../20120714122000_add_workflows_type.rb | 9 + .../20120714122100_update_workflows_to_sti.rb | 9 + ...0120714122200_add_workflows_rule_fields.rb | 11 + .../20120731164049_add_boards_parent_id.rb | 9 + ...120930112914_add_journals_private_notes.rb | 9 + ...26002032_add_enumerations_position_name.rb | 9 + ...537_populate_enumerations_position_name.rb | 9 + db/migrate/20121209123234_add_queries_type.rb | 9 + .../20121209123358_update_queries_to_sti.rb | 9 + ...13084931_add_attachments_disk_directory.rb | 9 + ...30110122628_split_documents_permissions.rb | 23 + ...184705_add_unique_index_on_tokens_value.rb | 15 + ...0202090625_add_projects_inherit_members.rb | 9 + ..._unique_index_on_custom_fields_trackers.rb | 24 + ..._unique_index_on_custom_fields_projects.rb | 24 + ...721_change_users_lastname_length_to_255.rb | 9 + .../20130215111127_add_issues_closed_on.rb | 9 + ...0130215111141_populate_issues_closed_on.rb | 25 + ...7094251_remove_issues_default_fk_values.rb | 19 + ...725021433_acts_as_taggable_on_migration.rb | 30 + db/migrate/20130725122407_create_bids.rb | 13 + .../20130725132508_create_biding_projects.rb | 12 + ...0727021306_create_journals_for_messages.rb | 14 + .../20130728021709_add_commit_to_bids.rb | 5 + db/schema.rb | 741 +++ doc/CHANGELOG | 2451 +++++++++ doc/COPYING | 339 ++ doc/INSTALL | 106 + doc/README_FOR_APP | 28 + doc/RUNNING_TESTS | 69 + doc/UPGRADING | 79 + extra/mail_handler/rdm-mailhandler.rb | 162 + extra/sample_plugin/README | 15 + .../app/controllers/example_controller.rb | 20 + extra/sample_plugin/app/models/meeting.rb | 11 + .../app/views/example/say_goodbye.html.erb | 7 + .../app/views/example/say_hello.html.erb | 15 + .../views/my/blocks/_sample_block.html.erb | 3 + .../settings/_sample_plugin_settings.html.erb | 3 + .../sample_plugin/assets/images/it_works.png | Bin 0 -> 3593 bytes .../assets/stylesheets/example.css | 1 + extra/sample_plugin/config/locales/en.yml | 6 + extra/sample_plugin/config/locales/fr.yml | 6 + extra/sample_plugin/config/routes.rb | 7 + .../db/migrate/001_create_meetings.rb | 15 + extra/sample_plugin/init.rb | 27 + .../test/integration/routing_test.rb | 12 + extra/svn/Redmine.pm | 544 ++ extra/svn/reposman.rb | 289 + ...1340_2f0b01a362fe0cdd98bbadd22ea6e1cc.pptx | Bin 0 -> 325033 bytes files/2013/07/130729153346_737521_50.jpg | Bin 0 -> 1264 bytes files/delete.me | 1 + lib/SVG/GPL.txt | 340 ++ lib/SVG/Graph/Bar.rb | 148 + lib/SVG/Graph/BarBase.rb | 139 + lib/SVG/Graph/BarHorizontal.rb | 149 + lib/SVG/Graph/Graph.rb | 978 ++++ lib/SVG/Graph/Line.rb | 444 ++ lib/SVG/Graph/Pie.rb | 395 ++ lib/SVG/Graph/Plot.rb | 500 ++ lib/SVG/Graph/Schedule.rb | 373 ++ lib/SVG/Graph/TimeSeries.rb | 238 + lib/SVG/LICENSE.txt | 57 + lib/diff.rb | 282 + lib/generators/redmine_plugin/USAGE | 26 + .../redmine_plugin_generator.rb | 37 + .../redmine_plugin/templates/README.rdoc | 3 + .../templates/en_rails_i18n.yml | 3 + .../redmine_plugin/templates/init.rb.erb | 8 + .../redmine_plugin/templates/routes.rb | 2 + .../templates/test_helper.rb.erb | 2 + .../redmine_plugin_controller/USAGE | 5 + .../redmine_plugin_controller_generator.rb | 27 + .../templates/controller.rb.erb | 9 + .../templates/functional_test.rb.erb | 8 + .../templates/helper.rb.erb | 2 + .../templates/view.html.erb | 1 + lib/generators/redmine_plugin_model/USAGE | 5 + .../redmine_plugin_model_generator.rb | 41 + .../templates/migration.rb | 15 + .../templates/model.rb.erb | 3 + .../templates/unit_test.rb.erb | 9 + lib/plugins/acts-as-taggable-on/.rspec | 2 + lib/plugins/acts-as-taggable-on/.travis.yml | 9 + lib/plugins/acts-as-taggable-on/Appraisals | 7 + lib/plugins/acts-as-taggable-on/Gemfile | 5 + lib/plugins/acts-as-taggable-on/Guardfile | 5 + lib/plugins/acts-as-taggable-on/LICENSE.md | 20 + lib/plugins/acts-as-taggable-on/README.md | 303 ++ lib/plugins/acts-as-taggable-on/Rakefile | 13 + .../acts-as-taggable-on.gemspec | 35 + .../gemfiles/rails_3.gemfile | 8 + .../gemfiles/rails_4.gemfile | 8 + .../lib/acts-as-taggable-on.rb | 65 + .../acts_as_taggable_on/cache.rb | 53 + .../acts_as_taggable_on/collection.rb | 183 + .../acts_as_taggable_on/compatibility.rb | 34 + .../acts_as_taggable_on/core.rb | 388 ++ .../acts_as_taggable_on/dirty.rb | 37 + .../acts_as_taggable_on/ownership.rb | 135 + .../acts_as_taggable_on/related.rb | 84 + .../lib/acts_as_taggable_on/tag.rb | 99 + .../lib/acts_as_taggable_on/tag_list.rb | 101 + .../lib/acts_as_taggable_on/taggable.rb | 105 + .../lib/acts_as_taggable_on/tagger.rb | 76 + .../lib/acts_as_taggable_on/tagging.rb | 34 + .../lib/acts_as_taggable_on/tags_helper.rb | 15 + .../lib/acts_as_taggable_on/utils.rb | 34 + .../lib/acts_as_taggable_on/version.rb | 4 + .../migration/migration_generator.rb | 39 + .../templates/active_record/migration.rb | 30 + .../acts_as_taggable_on_spec.rb | 264 + .../acts_as_tagger_spec.rb | 114 + .../spec/acts_as_taggable_on/caching_spec.rb | 77 + .../spec/acts_as_taggable_on/related_spec.rb | 143 + .../single_table_inheritance_spec.rb | 187 + .../spec/acts_as_taggable_on/tag_list_spec.rb | 126 + .../spec/acts_as_taggable_on/tag_spec.rb | 211 + .../spec/acts_as_taggable_on/taggable_spec.rb | 623 +++ .../spec/acts_as_taggable_on/tagger_spec.rb | 137 + .../spec/acts_as_taggable_on/tagging_spec.rb | 28 + .../acts_as_taggable_on/tags_helper_spec.rb | 44 + .../spec/acts_as_taggable_on/utils_spec.rb | 21 + lib/plugins/acts-as-taggable-on/spec/bm.rb | 52 + .../spec/database.yml.sample | 19 + .../migration/migration_generator_spec.rb | 22 + .../acts-as-taggable-on/spec/models.rb | 58 + .../acts-as-taggable-on/spec/schema.rb | 61 + .../acts-as-taggable-on/spec/spec_helper.rb | 86 + lib/plugins/acts_as_activity_provider/init.rb | 2 + .../lib/acts_as_activity_provider.rb | 88 + lib/plugins/acts_as_attachable/init.rb | 2 + .../lib/acts_as_attachable.rb | 115 + lib/plugins/acts_as_customizable/init.rb | 2 + .../lib/acts_as_customizable.rb | 168 + lib/plugins/acts_as_event/init.rb | 2 + .../acts_as_event/lib/acts_as_event.rb | 96 + lib/plugins/acts_as_list/README | 23 + lib/plugins/acts_as_list/init.rb | 3 + .../lib/active_record/acts/list.rb | 279 + lib/plugins/acts_as_list/test/list_test.rb | 332 ++ lib/plugins/acts_as_searchable/init.rb | 2 + .../lib/acts_as_searchable.rb | 134 + lib/plugins/acts_as_tree/README | 26 + lib/plugins/acts_as_tree/Rakefile | 22 + lib/plugins/acts_as_tree/init.rb | 1 + .../lib/active_record/acts/tree.rb | 107 + .../acts_as_tree/test/abstract_unit.rb | 0 .../acts_as_tree/test/acts_as_tree_test.rb | 219 + lib/plugins/acts_as_tree/test/database.yml | 0 .../acts_as_tree/test/fixtures/mixin.rb | 0 .../acts_as_tree/test/fixtures/mixins.yml | 0 lib/plugins/acts_as_tree/test/schema.rb | 0 lib/plugins/acts_as_versioned/CHANGELOG | 74 + lib/plugins/acts_as_versioned/MIT-LICENSE | 20 + lib/plugins/acts_as_versioned/README | 28 + .../acts_as_versioned/RUNNING_UNIT_TESTS | 41 + lib/plugins/acts_as_versioned/Rakefile | 182 + lib/plugins/acts_as_versioned/init.rb | 1 + .../lib/acts_as_versioned.rb | 568 ++ .../acts_as_versioned/test/abstract_unit.rb | 41 + .../acts_as_versioned/test/database.yml | 18 + .../test/fixtures/authors.yml | 6 + .../test/fixtures/landmark.rb | 3 + .../test/fixtures/landmark_versions.yml | 7 + .../test/fixtures/landmarks.yml | 6 + .../test/fixtures/locked_pages.yml | 10 + .../test/fixtures/locked_pages_revisions.yml | 27 + .../migrations/1_add_versioned_tables.rb | 13 + .../acts_as_versioned/test/fixtures/page.rb | 43 + .../test/fixtures/page_versions.yml | 16 + .../acts_as_versioned/test/fixtures/pages.yml | 7 + .../acts_as_versioned/test/fixtures/widget.rb | 6 + .../acts_as_versioned/test/migration_test.rb | 46 + lib/plugins/acts_as_versioned/test/schema.rb | 68 + .../acts_as_versioned/test/versioned_test.rb | 347 ++ lib/plugins/acts_as_watchable/init.rb | 3 + .../lib/acts_as_watchable.rb | 93 + lib/plugins/awesome_nested_set/.autotest | 13 + lib/plugins/awesome_nested_set/.travis.yml | 14 + lib/plugins/awesome_nested_set/CHANGELOG | 14 + lib/plugins/awesome_nested_set/MIT-LICENSE | 20 + lib/plugins/awesome_nested_set/README.rdoc | 100 + lib/plugins/awesome_nested_set/Rakefile | 28 + .../awesome_nested_set.gemspec | 22 + lib/plugins/awesome_nested_set/init.rb | 1 + .../lib/awesome_nested_set.rb | 7 + .../awesome_nested_set/awesome_nested_set.rb | 601 +++ .../lib/awesome_nested_set/helper.rb | 44 + .../lib/awesome_nested_set/version.rb | 3 + lib/plugins/awesome_nested_set/rails/init.rb | 13 + .../spec/awesome_nested_set/helper_spec.rb | 67 + .../spec/awesome_nested_set_spec.rb | 841 +++ .../awesome_nested_set/spec/db/database.yml | 18 + .../awesome_nested_set/spec/db/schema.rb | 45 + .../spec/fixtures/brokens.yml | 3 + .../spec/fixtures/categories.yml | 34 + .../spec/fixtures/departments.yml | 3 + .../spec/fixtures/notes.yml | 38 + .../spec/fixtures/things.yml | 27 + .../awesome_nested_set/spec/spec_helper.rb | 32 + .../awesome_nested_set/spec/support/models.rb | 72 + .../test/awesome_nested_set/helper_test.rb | 41 + .../test/awesome_nested_set_test.rb | 603 +++ .../awesome_nested_set/test/db/database.yml | 18 + .../awesome_nested_set/test/db/schema.rb | 23 + .../test/fixtures/categories.yml | 34 + .../test/fixtures/category.rb | 15 + .../test/fixtures/departments.yml | 3 + .../test/fixtures/notes.yml | 38 + .../awesome_nested_set/test/test_helper.rb | 31 + lib/plugins/gravatar/.gitignore | 1 + lib/plugins/gravatar/MIT-LICENSE | 20 + lib/plugins/gravatar/README.rdoc | 55 + lib/plugins/gravatar/Rakefile | 32 + lib/plugins/gravatar/about.yml | 7 + lib/plugins/gravatar/init.rb | 2 + lib/plugins/gravatar/lib/gravatar.rb | 88 + lib/plugins/gravatar/spec/gravatar_spec.rb | 43 + lib/plugins/open_id_authentication/CHANGELOG | 37 + lib/plugins/open_id_authentication/README | 223 + lib/plugins/open_id_authentication/Rakefile | 22 + ...open_id_authentication_tables_generator.rb | 11 + .../templates/migration.rb | 20 + .../templates/migration.rb | 26 + ...open_id_authentication_tables_generator.rb | 11 + lib/plugins/open_id_authentication/init.rb | 12 + .../lib/open_id_authentication.rb | 159 + .../lib/open_id_authentication/association.rb | 9 + .../lib/open_id_authentication/db_store.rb | 55 + .../open_id_authentication/mem_cache_store.rb | 73 + .../lib/open_id_authentication/nonce.rb | 5 + .../lib/open_id_authentication/request.rb | 23 + .../open_id_authentication/timeout_fixes.rb | 20 + .../tasks/open_id_authentication_tasks.rake | 30 + .../test/mem_cache_store_test.rb | 151 + .../test/normalize_test.rb | 32 + .../test/open_id_authentication_test.rb | 46 + .../test/status_test.rb | 14 + .../test/test_helper.rb | 17 + lib/plugins/rfpdf/CHANGELOG | 14 + lib/plugins/rfpdf/MIT-LICENSE | 20 + lib/plugins/rfpdf/README | 41 + lib/plugins/rfpdf/init.rb | 6 + lib/plugins/rfpdf/lib/config/lang/eng.rb | 48 + lib/plugins/rfpdf/lib/core/image_science.rb | 64 + lib/plugins/rfpdf/lib/core/rfpdf.rb | 298 ++ lib/plugins/rfpdf/lib/core/rmagick.rb | 64 + lib/plugins/rfpdf/lib/fonts/.noencode | 0 .../rfpdf/lib/fonts/DejaVuSans-Bold.ctg.z | Bin 0 -> 8509 bytes lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.z | Bin 0 -> 263826 bytes .../lib/fonts/DejaVuSans-BoldOblique.ctg.z | Bin 0 -> 7812 bytes .../rfpdf/lib/fonts/DejaVuSans-BoldOblique.z | Bin 0 -> 254774 bytes .../rfpdf/lib/fonts/DejaVuSans-Oblique.ctg.z | Bin 0 -> 7813 bytes .../rfpdf/lib/fonts/DejaVuSans-Oblique.z | Bin 0 -> 252470 bytes lib/plugins/rfpdf/lib/fonts/DejaVuSans.ctg.z | Bin 0 -> 8517 bytes lib/plugins/rfpdf/lib/fonts/DejaVuSans.z | Bin 0 -> 279448 bytes lib/plugins/rfpdf/lib/fonts/FreeSans.ctg.z | Bin 0 -> 4481 bytes lib/plugins/rfpdf/lib/fonts/FreeSans.z | Bin 0 -> 148324 bytes .../rfpdf/lib/fonts/FreeSansBold.ctg.z | Bin 0 -> 2193 bytes lib/plugins/rfpdf/lib/fonts/FreeSansBold.z | Bin 0 -> 46328 bytes .../rfpdf/lib/fonts/FreeSansBoldOblique.ctg.z | Bin 0 -> 2039 bytes .../rfpdf/lib/fonts/FreeSansBoldOblique.z | Bin 0 -> 45965 bytes .../rfpdf/lib/fonts/FreeSansOblique.ctg.z | Bin 0 -> 2317 bytes lib/plugins/rfpdf/lib/fonts/FreeSansOblique.z | Bin 0 -> 55670 bytes lib/plugins/rfpdf/lib/fonts/README.z | 2 + .../rfpdf/lib/fonts/dejavu-ttf-2.15/AUTHORS | 38 + .../rfpdf/lib/fonts/dejavu-ttf-2.15/BUGS | 3 + .../rfpdf/lib/fonts/dejavu-ttf-2.15/LICENSE | 98 + .../rfpdf/lib/fonts/dejavu-ttf-2.15/NEWS | 789 +++ .../rfpdf/lib/fonts/dejavu-ttf-2.15/README | 59 + .../lib/fonts/dejavu-ttf-2.15/langcover.txt | 187 + .../lib/fonts/dejavu-ttf-2.15/status.txt | 4641 +++++++++++++++++ .../lib/fonts/dejavu-ttf-2.15/unicover.txt | 160 + lib/plugins/rfpdf/lib/fonts/dejavusans.rb | 287 + lib/plugins/rfpdf/lib/fonts/dejavusansb.rb | 287 + lib/plugins/rfpdf/lib/fonts/dejavusansi.rb | 267 + lib/plugins/rfpdf/lib/fonts/freefont/AUTHORS | 143 + lib/plugins/rfpdf/lib/fonts/freefont/CREDITS | 389 ++ .../rfpdf/lib/fonts/freefont/ChangeLog | 630 +++ lib/plugins/rfpdf/lib/fonts/freefont/INSTALL | 57 + lib/plugins/rfpdf/lib/fonts/freefont/README | 113 + lib/plugins/rfpdf/lib/fonts/freesans.rb | 149 + lib/plugins/rfpdf/lib/fonts/freesansb.rb | 79 + lib/plugins/rfpdf/lib/fonts/freesansbi.rb | 76 + lib/plugins/rfpdf/lib/fonts/freesansi.rb | 85 + lib/plugins/rfpdf/lib/fonts/helvetica.rb | 4 + lib/plugins/rfpdf/lib/fonts/helveticab.rb | 15 + lib/plugins/rfpdf/lib/fonts/helveticabi.rb | 15 + lib/plugins/rfpdf/lib/fonts/helveticai.rb | 15 + lib/plugins/rfpdf/lib/fonts/old/.noencode | 0 .../rfpdf/lib/fonts/old/makefont/cp1250.map | 251 + .../rfpdf/lib/fonts/old/makefont/cp1251.map | 255 + .../rfpdf/lib/fonts/old/makefont/cp1252.map | 251 + .../rfpdf/lib/fonts/old/makefont/cp1253.map | 239 + .../rfpdf/lib/fonts/old/makefont/cp1254.map | 249 + .../rfpdf/lib/fonts/old/makefont/cp1255.map | 233 + .../rfpdf/lib/fonts/old/makefont/cp1257.map | 244 + .../rfpdf/lib/fonts/old/makefont/cp1258.map | 247 + .../rfpdf/lib/fonts/old/makefont/cp874.map | 225 + .../lib/fonts/old/makefont/iso-8859-1.map | 256 + .../lib/fonts/old/makefont/iso-8859-11.map | 248 + .../lib/fonts/old/makefont/iso-8859-15.map | 256 + .../lib/fonts/old/makefont/iso-8859-16.map | 256 + .../lib/fonts/old/makefont/iso-8859-2.map | 256 + .../lib/fonts/old/makefont/iso-8859-4.map | 256 + .../lib/fonts/old/makefont/iso-8859-5.map | 256 + .../lib/fonts/old/makefont/iso-8859-7.map | 250 + .../lib/fonts/old/makefont/iso-8859-9.map | 256 + .../rfpdf/lib/fonts/old/makefont/koi8-r.map | 256 + .../rfpdf/lib/fonts/old/makefont/koi8-u.map | 256 + .../rfpdf/lib/fonts/old/makefont/makefont.php | 411 ++ .../ttf-bitstream-vera-1.10/COPYRIGHT.TXT | 124 + .../fonts/ttf-bitstream-vera-1.10/README.TXT | 11 + .../ttf-bitstream-vera-1.10/RELEASENOTES.TXT | 162 + .../fonts/ttf-bitstream-vera-1.10/local.conf | 32 + .../rfpdf/lib/fonts/ttf2ufm/README.TXT | 30 + .../lib/fonts/ttf2ufm/makefontuni_ruby.php | 313 ++ lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm | Bin 0 -> 173188 bytes .../rfpdf/lib/fonts/ttf2ufm/ttf2ufm.exe | Bin 0 -> 257984 bytes lib/plugins/rfpdf/lib/fpdf/bookmark.rb | 99 + lib/plugins/rfpdf/lib/fpdf/chinese.rb | 486 ++ lib/plugins/rfpdf/lib/fpdf/fpdf_eps.rb | 139 + lib/plugins/rfpdf/lib/fpdf/japanese.rb | 481 ++ lib/plugins/rfpdf/lib/fpdf/korean.rb | 449 ++ lib/plugins/rfpdf/lib/fpdf/makefont.rb | 1787 +++++++ lib/plugins/rfpdf/lib/rfpdf.rb | 40 + .../rfpdf/lib/rfpdf/action_controller.rb | 40 + lib/plugins/rfpdf/lib/rfpdf/action_view.rb | 12 + lib/plugins/rfpdf/lib/rfpdf/errors.rb | 6 + lib/plugins/rfpdf/lib/rfpdf/fpdf.rb | 1632 ++++++ lib/plugins/rfpdf/lib/rfpdf/math.rb | 90 + .../rfpdf/template_handler/compile_support.rb | 73 + .../rfpdf/lib/rfpdf/template_handlers/base.rb | 12 + lib/plugins/rfpdf/lib/tcpdf.rb | 4349 +++++++++++++++ lib/plugins/rfpdf/logo_example.png | Bin 0 -> 19411 bytes lib/plugins/rfpdf/test/test_helper.rb | 1 + lib/plugins/rfpdf/test_unicode.rfpdf | 115 + lib/plugins/rfpdf/utf8test.txt | 135 + lib/redcloth3.rb | 1208 +++++ lib/redmine.rb | 300 ++ lib/redmine/access_control.rb | 135 + lib/redmine/access_keys.rb | 31 + lib/redmine/activity.rb | 46 + lib/redmine/activity/fetcher.rb | 95 + lib/redmine/ciphering.rb | 103 + lib/redmine/codeset_util.rb | 161 + lib/redmine/configuration.rb | 114 + lib/redmine/core_ext.rb | 1 + lib/redmine/core_ext/active_record.rb | 52 + lib/redmine/core_ext/date.rb | 5 + lib/redmine/core_ext/date/calculations.rb | 35 + lib/redmine/core_ext/string.rb | 11 + lib/redmine/core_ext/string/conversions.rb | 49 + lib/redmine/core_ext/string/inflections.rb | 29 + lib/redmine/custom_field_format.rb | 108 + lib/redmine/default_data/loader.rb | 185 + lib/redmine/export/pdf.rb | 807 +++ lib/redmine/helpers/calendar.rb | 85 + lib/redmine/helpers/diff.rb | 73 + lib/redmine/helpers/gantt.rb | 943 ++++ lib/redmine/helpers/time_report.rb | 151 + lib/redmine/hook.rb | 166 + lib/redmine/i18n.rb | 184 + lib/redmine/imap.rb | 60 + lib/redmine/info.rb | 29 + lib/redmine/menu_manager.rb | 435 ++ lib/redmine/mime_type.rb | 98 + lib/redmine/notifiable.rb | 26 + lib/redmine/pagination.rb | 300 ++ lib/redmine/platform.rb | 27 + lib/redmine/plugin.rb | 476 ++ lib/redmine/pop3.rb | 62 + lib/redmine/safe_attributes.rb | 87 + lib/redmine/scm/adapters/abstract_adapter.rb | 450 ++ lib/redmine/scm/adapters/bazaar_adapter.rb | 341 ++ lib/redmine/scm/adapters/cvs_adapter.rb | 462 ++ lib/redmine/scm/adapters/darcs_adapter.rb | 242 + .../scm/adapters/filesystem_adapter.rb | 118 + lib/redmine/scm/adapters/git_adapter.rb | 412 ++ .../adapters/mercurial/hg-template-1.0.tmpl | 12 + .../scm/adapters/mercurial/redminehelper.py | 220 + lib/redmine/scm/adapters/mercurial_adapter.rb | 341 ++ .../scm/adapters/subversion_adapter.rb | 291 ++ lib/redmine/scm/base.rb | 23 + lib/redmine/search.rb | 72 + lib/redmine/subclass_factory.rb | 47 + lib/redmine/syntax_highlighting.rb | 56 + lib/redmine/themes.rb | 127 + lib/redmine/thumbnail.rb | 55 + lib/redmine/unified_diff.rb | 294 ++ lib/redmine/utils.rb | 118 + lib/redmine/version.rb | 37 + lib/redmine/views/api_template_handler.rb | 26 + lib/redmine/views/builders.rb | 38 + lib/redmine/views/builders/json.rb | 45 + lib/redmine/views/builders/structure.rb | 83 + lib/redmine/views/builders/xml.rb | 47 + lib/redmine/views/labelled_form_builder.rb | 51 + lib/redmine/views/my_page/block.rb | 32 + lib/redmine/views/other_formats_builder.rb | 33 + lib/redmine/wiki_formatting.rb | 173 + lib/redmine/wiki_formatting/macros.rb | 247 + .../wiki_formatting/textile/formatter.rb | 134 + lib/redmine/wiki_formatting/textile/helper.rb | 46 + lib/tasks/ci.rake | 63 + lib/tasks/ciphering.rake | 35 + lib/tasks/deprecated.rake | 12 + lib/tasks/email.rake | 198 + lib/tasks/extract_fixtures.rake | 22 + lib/tasks/initializers.rake | 24 + lib/tasks/jdbc.rake | 8 + lib/tasks/load_default_data.rake | 35 + lib/tasks/locales.rake | 183 + lib/tasks/metrics.rake | 6 + lib/tasks/migrate_from_mantis.rake | 512 ++ lib/tasks/migrate_from_trac.rake | 771 +++ lib/tasks/permissions.rake | 9 + lib/tasks/redmine.rake | 126 + lib/tasks/reminder.rake | 43 + lib/tasks/testing.rake | 110 + lib/tasks/yardoc.rake | 21 + plugins/README | 1 + public/404.html | 23 + public/500.html | 25 + public/application.css | 1148 ++++ public/dispatch.fcgi.example | 20 + public/favicon.ico | Bin 0 -> 10415 bytes public/favicon.old.ico | Bin 0 -> 7886 bytes public/help/wiki_syntax.html | 66 + public/help/wiki_syntax_detailed.html | 281 + public/htaccess.fcgi.example | 49 + public/images/115960_50.jpg | Bin 0 -> 1570 bytes public/images/121944_50.jpg | Bin 0 -> 1306 bytes public/images/12_50.png | Bin 0 -> 5867 bytes public/images/1downarrow.png | Bin 0 -> 228 bytes public/images/1uparrow.png | Bin 0 -> 220 bytes public/images/233683_50.jpg | Bin 0 -> 1446 bytes public/images/28_50.jpg | Bin 0 -> 1302 bytes public/images/2downarrow.png | Bin 0 -> 282 bytes public/images/2uparrow.png | Bin 0 -> 292 bytes public/images/47318_50.jpg | Bin 0 -> 1402 bytes public/images/737521_50.jpg | Bin 0 -> 1264 bytes public/images/860270_50.jpg | Bin 0 -> 1598 bytes public/images/926055_50.jpg | Bin 0 -> 1336 bytes public/images/add.png | Bin 0 -> 680 bytes public/images/arrow_collapsed.png | Bin 0 -> 165 bytes public/images/arrow_down.png | Bin 0 -> 115 bytes public/images/arrow_expanded.png | Bin 0 -> 157 bytes public/images/attachment.png | Bin 0 -> 939 bytes public/images/avatars/AnonymousUser/0 | Bin 0 -> 1306 bytes public/images/avatars/Project/0 | Bin 0 -> 1598 bytes public/images/avatars/Project/6314 | Bin 0 -> 36513 bytes public/images/avatars/User/0 | Bin 0 -> 1306 bytes public/images/avatars/User/1 | Bin 0 -> 775702 bytes public/images/avatars/User/4245 | Bin 0 -> 6818 bytes public/images/avatars/User/4246 | Bin 0 -> 1446 bytes public/images/avatars/User/4247 | Bin 0 -> 6176 bytes public/images/avatars/User/4249 | Bin 0 -> 5894 bytes public/images/avatars/User/4275 | Bin 0 -> 18622 bytes public/images/avatars/User/4288 | Bin 0 -> 2841 bytes public/images/avatars/User/4856 | Bin 0 -> 6369 bytes public/images/avatars/User/4858 | Bin 0 -> 6183 bytes public/images/avatars/User/4859 | Bin 0 -> 18622 bytes public/images/avatars/User/4861 | Bin 0 -> 845941 bytes public/images/avatars/User/4863 | Bin 0 -> 1306 bytes public/images/bullet_add.png | Bin 0 -> 233 bytes public/images/bullet_arrow_left.png | Bin 0 -> 161 bytes public/images/bullet_arrow_right.png | Bin 0 -> 165 bytes public/images/bullet_black.png | Bin 0 -> 171 bytes public/images/bullet_blue.png | Bin 0 -> 241 bytes public/images/bullet_delete.png | Bin 0 -> 255 bytes public/images/bullet_diamond.png | Bin 0 -> 262 bytes public/images/bullet_end.png | Bin 0 -> 329 bytes public/images/bullet_go.png | Bin 0 -> 357 bytes public/images/bullet_orange.png | Bin 0 -> 268 bytes public/images/bullet_purple.png | Bin 0 -> 244 bytes public/images/bullet_toggle_minus.png | Bin 0 -> 218 bytes public/images/bullet_toggle_plus.png | Bin 0 -> 217 bytes public/images/calendar.png | Bin 0 -> 622 bytes public/images/cancel.png | Bin 0 -> 319 bytes public/images/changeset.png | Bin 0 -> 459 bytes public/images/close.png | Bin 0 -> 121 bytes public/images/close_hl.png | Bin 0 -> 121 bytes public/images/comment.png | Bin 0 -> 360 bytes public/images/comments.png | Bin 0 -> 501 bytes public/images/copy.png | Bin 0 -> 925 bytes public/images/database_key.png | Bin 0 -> 727 bytes public/images/delete.png | Bin 0 -> 911 bytes public/images/document.png | Bin 0 -> 333 bytes public/images/draft.png | Bin 0 -> 1885 bytes public/images/duplicate.png | Bin 0 -> 960 bytes public/images/edit.png | Bin 0 -> 522 bytes public/images/exclamation.png | Bin 0 -> 648 bytes public/images/external.png | Bin 0 -> 136 bytes public/images/false.png | Bin 0 -> 459 bytes public/images/fav.png | Bin 0 -> 378 bytes public/images/fav_off.png | Bin 0 -> 211 bytes public/images/feed.png | Bin 0 -> 427 bytes public/images/files/c.png | Bin 0 -> 534 bytes public/images/files/csharp.png | Bin 0 -> 647 bytes public/images/files/css.png | Bin 0 -> 665 bytes public/images/files/default.png | Bin 0 -> 241 bytes public/images/files/html.png | Bin 0 -> 734 bytes public/images/files/image.png | Bin 0 -> 597 bytes public/images/files/java.png | Bin 0 -> 639 bytes public/images/files/js.png | Bin 0 -> 624 bytes public/images/files/pdf.png | Bin 0 -> 538 bytes public/images/files/php.png | Bin 0 -> 485 bytes public/images/files/ruby.png | Bin 0 -> 573 bytes public/images/files/text.png | Bin 0 -> 289 bytes public/images/files/xml.png | Bin 0 -> 550 bytes public/images/files/zip.png | Bin 0 -> 713 bytes public/images/folder.png | Bin 0 -> 349 bytes public/images/folder_open.png | Bin 0 -> 471 bytes public/images/folder_open_add.png | Bin 0 -> 584 bytes public/images/folder_open_orange.png | Bin 0 -> 585 bytes public/images/group.png | Bin 0 -> 700 bytes public/images/help.png | Bin 0 -> 733 bytes public/images/history.png | Bin 0 -> 204 bytes public/images/home_images/2.png | Bin 0 -> 11735 bytes public/images/home_images/3.png | Bin 0 -> 7005 bytes public/images/home_images/BackGround.gif | Bin 0 -> 72629 bytes public/images/home_images/logo1.png | Bin 0 -> 9213 bytes public/images/home_new.png | Bin 0 -> 9213 bytes public/images/home_project.png | Bin 0 -> 7005 bytes public/images/home_req.png | Bin 0 -> 11735 bytes public/images/hourglass.png | Bin 0 -> 744 bytes public/images/jstoolbar/bt_bq.png | Bin 0 -> 384 bytes public/images/jstoolbar/bt_bq_remove.png | Bin 0 -> 379 bytes public/images/jstoolbar/bt_code.png | Bin 0 -> 927 bytes public/images/jstoolbar/bt_del.png | Bin 0 -> 252 bytes public/images/jstoolbar/bt_em.png | Bin 0 -> 197 bytes public/images/jstoolbar/bt_h1.png | Bin 0 -> 247 bytes public/images/jstoolbar/bt_h2.png | Bin 0 -> 252 bytes public/images/jstoolbar/bt_h3.png | Bin 0 -> 261 bytes public/images/jstoolbar/bt_img.png | Bin 0 -> 1027 bytes public/images/jstoolbar/bt_ins.png | Bin 0 -> 937 bytes public/images/jstoolbar/bt_link.png | Bin 0 -> 293 bytes public/images/jstoolbar/bt_ol.png | Bin 0 -> 248 bytes public/images/jstoolbar/bt_pre.png | Bin 0 -> 918 bytes public/images/jstoolbar/bt_strong.png | Bin 0 -> 244 bytes public/images/jstoolbar/bt_ul.png | Bin 0 -> 249 bytes public/images/jstoolbar/logo1.png | Bin 0 -> 9213 bytes public/images/lightning.png | Bin 0 -> 584 bytes public/images/link.png | Bin 0 -> 306 bytes public/images/link_break.png | Bin 0 -> 657 bytes public/images/loading.gif | Bin 0 -> 1553 bytes public/images/locked.png | Bin 0 -> 1013 bytes public/images/logo-only_med.png | Bin 0 -> 20837 bytes public/images/magnifier.png | Bin 0 -> 615 bytes public/images/message.png | Bin 0 -> 365 bytes public/images/milestone_done.png | Bin 0 -> 137 bytes public/images/milestone_late.png | Bin 0 -> 160 bytes public/images/milestone_todo.png | Bin 0 -> 155 bytes public/images/move.png | Bin 0 -> 321 bytes public/images/new/fenxiang.png | Bin 0 -> 6022 bytes public/images/new/liuyan.png | Bin 0 -> 8326 bytes public/images/new/liuyan2.png | Bin 0 -> 10789 bytes public/images/new/logo.gif | Bin 0 -> 36513 bytes public/images/new/logo.png | Bin 0 -> 9010 bytes public/images/new/logo_top.png | Bin 0 -> 78098 bytes public/images/new/mlogo.png | Bin 0 -> 2317 bytes public/images/new/news.png | Bin 0 -> 199009 bytes public/images/new/small.png | Bin 0 -> 4930 bytes public/images/new/user.jpg | Bin 0 -> 1264 bytes public/images/new/zhishu.png | Bin 0 -> 4005 bytes public/images/new/zhishu2.png | Bin 0 -> 3654 bytes public/images/news.png | Bin 0 -> 605 bytes public/images/openid-bg.gif | Bin 0 -> 328 bytes public/images/package.png | Bin 0 -> 800 bytes public/images/pai.png | Bin 0 -> 3550 bytes public/images/plugin.png | Bin 0 -> 538 bytes public/images/project_marker.png | Bin 0 -> 204 bytes public/images/projects.png | Bin 0 -> 775 bytes public/images/reload.png | Bin 0 -> 549 bytes public/images/report.png | Bin 0 -> 1014 bytes public/images/requirements/req.jpg | Bin 0 -> 2380 bytes public/images/save.png | Bin 0 -> 440 bytes public/images/server_key.png | Bin 0 -> 746 bytes public/images/sidebar/fork.png | Bin 0 -> 2962 bytes public/images/sidebar/tag_title.png | Bin 0 -> 2985 bytes public/images/sidebar/tool_tag.png | Bin 0 -> 1088 bytes public/images/sidebar/watch.png | Bin 0 -> 2981 bytes public/images/sort_asc.png | Bin 0 -> 158 bytes public/images/sort_desc.png | Bin 0 -> 157 bytes public/images/stars_ro.png | Bin 0 -> 1176 bytes public/images/stats.png | Bin 0 -> 488 bytes public/images/table_multiple.png | Bin 0 -> 559 bytes public/images/task_done.png | Bin 0 -> 137 bytes public/images/task_late.png | Bin 0 -> 93 bytes public/images/task_parent_end.png | Bin 0 -> 224 bytes public/images/task_todo.png | Bin 0 -> 93 bytes public/images/text_list_bullets.png | Bin 0 -> 291 bytes public/images/textfield.png | Bin 0 -> 100 bytes public/images/textfield_key.png | Bin 0 -> 455 bytes public/images/ticket.png | Bin 0 -> 447 bytes public/images/ticket_checked.png | Bin 0 -> 535 bytes public/images/ticket_edit.png | Bin 0 -> 678 bytes public/images/ticket_go.png | Bin 0 -> 608 bytes public/images/ticket_note.png | Bin 0 -> 641 bytes public/images/time.png | Bin 0 -> 740 bytes public/images/time_add.png | Bin 0 -> 774 bytes public/images/toggle_check.png | Bin 0 -> 262 bytes public/images/true.png | Bin 0 -> 248 bytes public/images/unlock.png | Bin 0 -> 448 bytes public/images/user.png | Bin 0 -> 669 bytes public/images/user_images/L1.png | Bin 0 -> 10533 bytes public/images/user_images/L2.png | Bin 0 -> 12295 bytes public/images/user_images/L3.png | Bin 0 -> 7697 bytes public/images/user_images/fans.png | Bin 0 -> 51199 bytes public/images/user_images/fork.png | Bin 0 -> 2962 bytes public/images/user_images/in_share.png | Bin 0 -> 3921 bytes public/images/user_images/iuser.png | Bin 0 -> 10254 bytes public/images/user_images/m1.png | Bin 0 -> 33467 bytes public/images/user_images/m2.png | Bin 0 -> 45616 bytes public/images/user_images/me.jpg | Bin 0 -> 11550 bytes public/images/user_images/mlogo.png | Bin 0 -> 2317 bytes public/images/user_images/project.jpg | Bin 0 -> 1602 bytes public/images/user_images/project.png | Bin 0 -> 3556 bytes public/images/user_images/share.png | Bin 0 -> 4884 bytes public/images/user_images/user2.png | Bin 0 -> 5685 bytes public/images/user_images/watch.png | Bin 0 -> 2981 bytes public/images/user_images/watchers.png | Bin 0 -> 43357 bytes public/images/version_marker.png | Bin 0 -> 174 bytes public/images/warning.png | Bin 0 -> 613 bytes public/images/watcher/watcher_button.png | Bin 0 -> 4406 bytes public/images/welcome/1.png | Bin 0 -> 9990 bytes public/images/welcome/2.png | Bin 0 -> 6382 bytes public/images/welcome/3.png | Bin 0 -> 7840 bytes public/images/welcome/4.png | Bin 0 -> 102773 bytes public/images/welcome/background.png | Bin 0 -> 11862 bytes public/images/welcome/background2.png | Bin 0 -> 12451 bytes public/images/welcome/background3.png | Bin 0 -> 12651 bytes public/images/welcome/backgroundnew.png | Bin 0 -> 136766 bytes public/images/wiki_edit.png | Bin 0 -> 464 bytes public/images/zoom_in.png | Bin 0 -> 680 bytes public/images/zoom_out.png | Bin 0 -> 657 bytes public/javascripts/application.js | 595 +++ public/javascripts/attachments.js | 188 + public/javascripts/avatars.js | 181 + public/javascripts/context_menu.js | 236 + public/javascripts/gantt.js | 172 + .../i18n/jquery.ui.datepicker-ar.js | 23 + .../i18n/jquery.ui.datepicker-az.js | 23 + .../i18n/jquery.ui.datepicker-bg.js | 24 + .../i18n/jquery.ui.datepicker-bs.js | 23 + .../i18n/jquery.ui.datepicker-ca.js | 23 + .../i18n/jquery.ui.datepicker-cs.js | 23 + .../i18n/jquery.ui.datepicker-da.js | 23 + .../i18n/jquery.ui.datepicker-de.js | 23 + .../i18n/jquery.ui.datepicker-el.js | 23 + .../i18n/jquery.ui.datepicker-en-GB.js | 23 + .../i18n/jquery.ui.datepicker-es.js | 23 + .../i18n/jquery.ui.datepicker-et.js | 23 + .../i18n/jquery.ui.datepicker-eu.js | 23 + .../i18n/jquery.ui.datepicker-fa.js | 59 + .../i18n/jquery.ui.datepicker-fi.js | 23 + .../i18n/jquery.ui.datepicker-fr.js | 25 + .../i18n/jquery.ui.datepicker-gl.js | 23 + .../i18n/jquery.ui.datepicker-he.js | 23 + .../i18n/jquery.ui.datepicker-hr.js | 23 + .../i18n/jquery.ui.datepicker-hu.js | 23 + .../i18n/jquery.ui.datepicker-id.js | 23 + .../i18n/jquery.ui.datepicker-it.js | 23 + .../i18n/jquery.ui.datepicker-ja.js | 23 + .../i18n/jquery.ui.datepicker-ko.js | 23 + .../i18n/jquery.ui.datepicker-lt.js | 23 + .../i18n/jquery.ui.datepicker-lv.js | 23 + .../i18n/jquery.ui.datepicker-mk.js | 23 + .../i18n/jquery.ui.datepicker-nl.js | 23 + .../i18n/jquery.ui.datepicker-no.js | 23 + .../i18n/jquery.ui.datepicker-pl.js | 23 + .../i18n/jquery.ui.datepicker-pt-BR.js | 23 + .../i18n/jquery.ui.datepicker-pt.js | 22 + .../i18n/jquery.ui.datepicker-ro.js | 26 + .../i18n/jquery.ui.datepicker-ru.js | 23 + .../i18n/jquery.ui.datepicker-sk.js | 23 + .../i18n/jquery.ui.datepicker-sl.js | 24 + .../i18n/jquery.ui.datepicker-sq.js | 23 + .../i18n/jquery.ui.datepicker-sr.js | 23 + .../i18n/jquery.ui.datepicker-sv.js | 23 + .../i18n/jquery.ui.datepicker-th.js | 23 + .../i18n/jquery.ui.datepicker-tr.js | 23 + .../i18n/jquery.ui.datepicker-uk.js | 24 + .../i18n/jquery.ui.datepicker-vi.js | 23 + .../i18n/jquery.ui.datepicker-zh-CN.js | 23 + .../i18n/jquery.ui.datepicker-zh-TW.js | 23 + .../jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js | 11 + .../jstoolbar/jstoolbar-textile.min.js | 2 + public/javascripts/jstoolbar/jstoolbar.js | 374 ++ .../jstoolbar/lang/jstoolbar-ar.js | 16 + .../jstoolbar/lang/jstoolbar-az.js | 16 + .../jstoolbar/lang/jstoolbar-bg.js | 16 + .../jstoolbar/lang/jstoolbar-bs.js | 14 + .../jstoolbar/lang/jstoolbar-ca.js | 16 + .../jstoolbar/lang/jstoolbar-cs.js | 16 + .../jstoolbar/lang/jstoolbar-da.js | 16 + .../jstoolbar/lang/jstoolbar-de.js | 16 + .../jstoolbar/lang/jstoolbar-en-gb.js | 16 + .../jstoolbar/lang/jstoolbar-en.js | 16 + .../jstoolbar/lang/jstoolbar-es.js | 16 + .../jstoolbar/lang/jstoolbar-et.js | 33 + .../jstoolbar/lang/jstoolbar-eu.js | 20 + .../jstoolbar/lang/jstoolbar-fa.js | 16 + .../jstoolbar/lang/jstoolbar-fi.js | 16 + .../jstoolbar/lang/jstoolbar-fr.js | 16 + .../jstoolbar/lang/jstoolbar-gl.js | 16 + .../jstoolbar/lang/jstoolbar-he.js | 16 + .../jstoolbar/lang/jstoolbar-hr.js | 16 + .../jstoolbar/lang/jstoolbar-hu.js | 16 + .../jstoolbar/lang/jstoolbar-id.js | 16 + .../jstoolbar/lang/jstoolbar-it.js | 19 + .../jstoolbar/lang/jstoolbar-ja.js | 16 + .../jstoolbar/lang/jstoolbar-ko.js | 16 + .../jstoolbar/lang/jstoolbar-lt.js | 16 + .../jstoolbar/lang/jstoolbar-lv.js | 17 + .../jstoolbar/lang/jstoolbar-mk.js | 17 + .../jstoolbar/lang/jstoolbar-mn.js | 16 + .../jstoolbar/lang/jstoolbar-nl.js | 16 + .../jstoolbar/lang/jstoolbar-no.js | 16 + .../jstoolbar/lang/jstoolbar-pl.js | 17 + .../jstoolbar/lang/jstoolbar-pt-br.js | 18 + .../jstoolbar/lang/jstoolbar-pt.js | 17 + .../jstoolbar/lang/jstoolbar-ro.js | 16 + .../jstoolbar/lang/jstoolbar-ru.js | 16 + .../jstoolbar/lang/jstoolbar-sk.js | 16 + .../jstoolbar/lang/jstoolbar-sl.js | 16 + .../jstoolbar/lang/jstoolbar-sq.js | 16 + .../jstoolbar/lang/jstoolbar-sr-yu.js | 16 + .../jstoolbar/lang/jstoolbar-sr.js | 16 + .../jstoolbar/lang/jstoolbar-sv.js | 16 + .../jstoolbar/lang/jstoolbar-th.js | 16 + .../jstoolbar/lang/jstoolbar-tr.js | 14 + .../jstoolbar/lang/jstoolbar-uk.js | 16 + .../jstoolbar/lang/jstoolbar-vi.js | 16 + .../jstoolbar/lang/jstoolbar-zh-tw.js | 16 + .../jstoolbar/lang/jstoolbar-zh.js | 16 + public/javascripts/jstoolbar/textile.js | 211 + public/javascripts/project_identifier.js | 78 + public/javascripts/raphael.js | 10 + public/javascripts/repository_navigation.js | 33 + public/javascripts/revision_graph.js | 94 + public/javascripts/select_list_move.js | 83 + public/stylesheets/application.css | 1645 ++++++ public/stylesheets/context_menu.css | 52 + public/stylesheets/context_menu_rtl.css | 9 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_eef5fd_1x400.png | Bin 0 -> 113 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../ui-bg_gloss-wave_35_759fcf_500x100.png | Bin 0 -> 3945 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_759fcf_1x100.png | Bin 0 -> 126 bytes .../jquery/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_759fcf_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes public/stylesheets/jquery/jquery-ui-1.9.2.css | 5 + public/stylesheets/jstoolbar.css | 100 + public/stylesheets/rtl.css | 94 + public/stylesheets/scm.css | 104 + public/stylesheetsold/application.css | 1148 ++++ public/stylesheetsold/context_menu.css | 52 + public/stylesheetsold/context_menu_rtl.css | 9 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_eef5fd_1x400.png | Bin 0 -> 113 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../ui-bg_gloss-wave_35_759fcf_500x100.png | Bin 0 -> 3945 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_759fcf_1x100.png | Bin 0 -> 126 bytes .../jquery/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_759fcf_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes .../jquery/images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes .../stylesheetsold/jquery/jquery-ui-1.9.2.css | 5 + public/stylesheetsold/jstoolbar.css | 100 + public/stylesheetsold/rtl.css | 94 + public/stylesheetsold/scm.css | 104 + public/themes/README | 1 + .../alternate/stylesheets/application.css | 70 + public/themes/classic/images/home.png | Bin 0 -> 806 bytes public/themes/classic/images/wrench.png | Bin 0 -> 610 bytes .../classic/stylesheets/application.css | 41 + public/themes/redpenny-master/README.md | 12 + .../themes/redpenny-master/images/bg/bg.gif | Bin 0 -> 3440 bytes .../themes/redpenny-master/images/bg/bg.jpg | Bin 0 -> 23450 bytes public/themes/redpenny-master/images/bg/f.jpg | Bin 0 -> 15173 bytes .../themes/redpenny-master/images/bullet.png | Bin 0 -> 438 bytes public/themes/redpenny-master/images/logo.png | Bin 0 -> 6406 bytes .../stylesheets/application.css | 1505 ++++++ .../stylesheets/font/FontAwesome.otf | Bin 0 -> 50204 bytes .../stylesheets/font/fontawesome-webfont.eot | Bin 0 -> 29360 bytes .../stylesheets/font/fontawesome-webfont.svg | 339 ++ .../stylesheets/font/fontawesome-webfont.ttf | Bin 0 -> 64960 bytes .../stylesheets/font/fontawesome-webfont.woff | Bin 0 -> 34420 bytes .../redpenny-master/stylesheets/images/bg.png | Bin 0 -> 5706 bytes .../stylesheets/images/bg/bg.gif | Bin 0 -> 3440 bytes .../stylesheets/images/bg/bg.jpg | Bin 0 -> 23450 bytes .../stylesheets/images/bg/f.jpg | Bin 0 -> 15173 bytes .../stylesheets/images/bullet.png | Bin 0 -> 438 bytes .../stylesheets/images/log.png | Bin 0 -> 93046 bytes .../stylesheets/images/logo.png | Bin 0 -> 93046 bytes .../stylesheets/images/logo/bg.png | Bin 0 -> 5706 bytes script/about | 6 + script/rails | 6 + 1696 files changed, 163817 insertions(+) create mode 100644 .gitignore create mode 100644 .hgignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 README.rdoc create mode 100644 Rakefile create mode 100644 app/controllers/account_controller.rb create mode 100644 app/controllers/activities_controller.rb create mode 100644 app/controllers/admin_controller.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/attachments_controller.rb create mode 100644 app/controllers/auth_sources_controller.rb create mode 100644 app/controllers/auto_completes_controller.rb create mode 100644 app/controllers/avatar_controller.rb create mode 100644 app/controllers/bids_controller.rb create mode 100644 app/controllers/boards_controller.rb create mode 100644 app/controllers/calendars_controller.rb create mode 100644 app/controllers/comments_controller.rb create mode 100644 app/controllers/context_menus_controller.rb create mode 100644 app/controllers/custom_fields_controller.rb create mode 100644 app/controllers/documents_controller.rb create mode 100644 app/controllers/enumerations_controller.rb create mode 100644 app/controllers/files_controller.rb create mode 100644 app/controllers/gantts_controller.rb create mode 100644 app/controllers/groups_controller.rb create mode 100644 app/controllers/issue_categories_controller.rb create mode 100644 app/controllers/issue_relations_controller.rb create mode 100644 app/controllers/issue_statuses_controller.rb create mode 100644 app/controllers/issues_controller.rb create mode 100644 app/controllers/journals_controller.rb create mode 100644 app/controllers/list_controller.rb create mode 100644 app/controllers/mail_handler_controller.rb create mode 100644 app/controllers/members_controller.rb create mode 100644 app/controllers/messages_controller.rb create mode 100644 app/controllers/my_controller.rb create mode 100644 app/controllers/news_controller.rb create mode 100644 app/controllers/previews_controller.rb create mode 100644 app/controllers/project_enumerations_controller.rb create mode 100644 app/controllers/projects_controller.rb create mode 100644 app/controllers/queries_controller.rb create mode 100644 app/controllers/reports_controller.rb create mode 100644 app/controllers/repositories_controller.rb create mode 100644 app/controllers/roles_controller.rb create mode 100644 app/controllers/search_controller.rb create mode 100644 app/controllers/settings_controller.rb create mode 100644 app/controllers/sys_controller.rb create mode 100644 app/controllers/tags_controller.rb create mode 100644 app/controllers/test_controller.rb create mode 100644 app/controllers/timelog_controller.rb create mode 100644 app/controllers/trackers_controller.rb create mode 100644 app/controllers/users_controller.rb create mode 100644 app/controllers/versions_controller.rb create mode 100644 app/controllers/watchers_controller.rb create mode 100644 app/controllers/welcome_controller.rb create mode 100644 app/controllers/wiki_controller.rb create mode 100644 app/controllers/wikis_controller.rb create mode 100644 app/controllers/words_controller.rb create mode 100644 app/controllers/workflows_controller.rb create mode 100644 app/helpers/account_helper.rb create mode 100644 app/helpers/activities_helper.rb create mode 100644 app/helpers/admin_helper.rb create mode 100644 app/helpers/application_helper.rb create mode 100644 app/helpers/attachments_helper.rb create mode 100644 app/helpers/auth_sources_helper.rb create mode 100644 app/helpers/avatar_helper.rb create mode 100644 app/helpers/bids_helper.rb create mode 100644 app/helpers/boards_helper.rb create mode 100644 app/helpers/calendars_helper.rb create mode 100644 app/helpers/context_menus_helper.rb create mode 100644 app/helpers/custom_fields_helper.rb create mode 100644 app/helpers/documents_helper.rb create mode 100644 app/helpers/enumerations_helper.rb create mode 100644 app/helpers/gantt_helper.rb create mode 100644 app/helpers/groups_helper.rb create mode 100644 app/helpers/issue_categories_helper.rb create mode 100644 app/helpers/issue_relations_helper.rb create mode 100644 app/helpers/issue_statuses_helper.rb create mode 100644 app/helpers/issues_helper.rb create mode 100644 app/helpers/journals_helper.rb create mode 100644 app/helpers/mail_handler_helper.rb create mode 100644 app/helpers/members_helper.rb create mode 100644 app/helpers/messages_helper.rb create mode 100644 app/helpers/my_helper.rb create mode 100644 app/helpers/news_helper.rb create mode 100644 app/helpers/projects_helper.rb create mode 100644 app/helpers/queries_helper.rb create mode 100644 app/helpers/reports_helper.rb create mode 100644 app/helpers/repositories_helper.rb create mode 100644 app/helpers/roles_helper.rb create mode 100644 app/helpers/routes_helper.rb create mode 100644 app/helpers/search_helper.rb create mode 100644 app/helpers/settings_helper.rb create mode 100644 app/helpers/sort_helper.rb create mode 100644 app/helpers/test_helper.rb create mode 100644 app/helpers/timelog_helper.rb create mode 100644 app/helpers/trackers_helper.rb create mode 100644 app/helpers/users_helper.rb create mode 100644 app/helpers/versions_helper.rb create mode 100644 app/helpers/watchers_helper.rb create mode 100644 app/helpers/welcome_helper.rb create mode 100644 app/helpers/wiki_helper.rb create mode 100644 app/helpers/words_helper.rb create mode 100644 app/helpers/workflows_helper.rb create mode 100644 app/models/attachment.rb create mode 100644 app/models/auth_source.rb create mode 100644 app/models/auth_source_ldap.rb create mode 100644 app/models/bid.rb create mode 100644 app/models/biding_project.rb create mode 100644 app/models/board.rb create mode 100644 app/models/change.rb create mode 100644 app/models/changeset.rb create mode 100644 app/models/comment.rb create mode 100644 app/models/comment_observer.rb create mode 100644 app/models/custom_field.rb create mode 100644 app/models/custom_field_value.rb create mode 100644 app/models/custom_value.rb create mode 100644 app/models/document.rb create mode 100644 app/models/document_category.rb create mode 100644 app/models/document_category_custom_field.rb create mode 100644 app/models/document_observer.rb create mode 100644 app/models/enabled_module.rb create mode 100644 app/models/enumeration.rb create mode 100644 app/models/group.rb create mode 100644 app/models/group_custom_field.rb create mode 100644 app/models/issue.rb create mode 100644 app/models/issue_category.rb create mode 100644 app/models/issue_custom_field.rb create mode 100644 app/models/issue_observer.rb create mode 100644 app/models/issue_priority.rb create mode 100644 app/models/issue_priority_custom_field.rb create mode 100644 app/models/issue_query.rb create mode 100644 app/models/issue_relation.rb create mode 100644 app/models/issue_status.rb create mode 100644 app/models/journal.rb create mode 100644 app/models/journal_detail.rb create mode 100644 app/models/journal_observer.rb create mode 100644 app/models/journals_for_message.rb create mode 100644 app/models/mail_handler.rb create mode 100644 app/models/mailer.rb create mode 100644 app/models/member.rb create mode 100644 app/models/member_role.rb create mode 100644 app/models/message.rb create mode 100644 app/models/message_observer.rb create mode 100644 app/models/messages_for_bids.rb create mode 100644 app/models/messages_for_user.rb create mode 100644 app/models/news.rb create mode 100644 app/models/news_observer.rb create mode 100644 app/models/principal.rb create mode 100644 app/models/project.rb create mode 100644 app/models/project_custom_field.rb create mode 100644 app/models/project_tags.rb create mode 100644 app/models/query.rb create mode 100644 app/models/repository.rb create mode 100644 app/models/repository/bazaar.rb create mode 100644 app/models/repository/cvs.rb create mode 100644 app/models/repository/darcs.rb create mode 100644 app/models/repository/filesystem.rb create mode 100644 app/models/repository/git.rb create mode 100644 app/models/repository/mercurial.rb create mode 100644 app/models/repository/subversion.rb create mode 100644 app/models/role.rb create mode 100644 app/models/setting.rb create mode 100644 app/models/tag.rb create mode 100644 app/models/time_entry.rb create mode 100644 app/models/time_entry_activity.rb create mode 100644 app/models/time_entry_activity_custom_field.rb create mode 100644 app/models/time_entry_custom_field.rb create mode 100644 app/models/time_entry_query.rb create mode 100644 app/models/token.rb create mode 100644 app/models/tracker.rb create mode 100644 app/models/user.rb create mode 100644 app/models/user_custom_field.rb create mode 100644 app/models/user_extension.rb create mode 100644 app/models/user_preference.rb create mode 100644 app/models/version.rb create mode 100644 app/models/version_custom_field.rb create mode 100644 app/models/watcher.rb create mode 100644 app/models/watchers_of_projects.rb create mode 100644 app/models/watchers_of_user.rb create mode 100644 app/models/wiki.rb create mode 100644 app/models/wiki_content.rb create mode 100644 app/models/wiki_content_observer.rb create mode 100644 app/models/wiki_page.rb create mode 100644 app/models/wiki_redirect.rb create mode 100644 app/models/workflow_permission.rb create mode 100644 app/models/workflow_rule.rb create mode 100644 app/models/workflow_transition.rb create mode 100644 app/sweepers/NOTEMPTY create mode 100644 app/views/account/login.html.erb create mode 100644 app/views/account/logout.html.erb create mode 100644 app/views/account/lost_password.html.erb create mode 100644 app/views/account/password_recovery.html.erb create mode 100644 app/views/account/register.html.erb create mode 100644 app/views/activities/index.html.erb create mode 100644 app/views/admin/_menu.html.erb create mode 100644 app/views/admin/_no_data.html.erb create mode 100644 app/views/admin/index.html.erb create mode 100644 app/views/admin/info.html.erb create mode 100644 app/views/admin/plugins.html.erb create mode 100644 app/views/admin/projects.html.erb create mode 100644 app/views/attachments/_form.html.erb create mode 100644 app/views/attachments/_links.html.erb create mode 100644 app/views/attachments/destroy.js.erb create mode 100644 app/views/attachments/diff.html.erb create mode 100644 app/views/attachments/file.html.erb create mode 100644 app/views/attachments/show.api.rsb create mode 100644 app/views/attachments/upload.api.rsb create mode 100644 app/views/attachments/upload.js.erb create mode 100644 app/views/auth_sources/_form.html.erb create mode 100644 app/views/auth_sources/_form_auth_source_ldap.html.erb create mode 100644 app/views/auth_sources/edit.html.erb create mode 100644 app/views/auth_sources/index.html.erb create mode 100644 app/views/auth_sources/new.html.erb create mode 100644 app/views/auto_completes/issues.html.erb create mode 100644 app/views/avatar/_avatar_form.html.erb create mode 100644 app/views/avatar/upload.js.erb create mode 100644 app/views/bids/_history.html.erb create mode 100644 app/views/bids/_new.html.erb create mode 100644 app/views/bids/_project_list.html.erb create mode 100644 app/views/bids/add.js.erb create mode 100644 app/views/bids/back.js.erb create mode 100644 app/views/bids/create.js.erb create mode 100644 app/views/bids/destroy.js.erb create mode 100644 app/views/bids/index.html.erb create mode 100644 app/views/bids/more.js.erb create mode 100644 app/views/bids/new.js.erb create mode 100644 app/views/bids/new_bid.html.erb create mode 100644 app/views/bids/show.html.erb create mode 100644 app/views/bids/show_project.html.erb create mode 100644 app/views/boards/_form.html.erb create mode 100644 app/views/boards/edit.html.erb create mode 100644 app/views/boards/index.html.erb create mode 100644 app/views/boards/new.html.erb create mode 100644 app/views/boards/show.html.erb create mode 100644 app/views/calendars/show.html.erb create mode 100644 app/views/common/_calendar.html.erb create mode 100644 app/views/common/_diff.html.erb create mode 100644 app/views/common/_file.html.erb create mode 100644 app/views/common/_preview.html.erb create mode 100644 app/views/common/_project.html.erb create mode 100644 app/views/common/_tabs.html.erb create mode 100644 app/views/common/error.html.erb create mode 100644 app/views/common/error_messages.api.rsb create mode 100644 app/views/common/feed.atom.builder create mode 100644 app/views/context_menus/issues.html.erb create mode 100644 app/views/context_menus/time_entries.html.erb create mode 100644 app/views/custom_fields/_form.html.erb create mode 100644 app/views/custom_fields/_index.html.erb create mode 100644 app/views/custom_fields/edit.html.erb create mode 100644 app/views/custom_fields/index.html.erb create mode 100644 app/views/custom_fields/new.html.erb create mode 100644 app/views/custom_fields/new.js.erb create mode 100644 app/views/documents/_document.html.erb create mode 100644 app/views/documents/_form.html.erb create mode 100644 app/views/documents/edit.html.erb create mode 100644 app/views/documents/index.html.erb create mode 100644 app/views/documents/new.html.erb create mode 100644 app/views/documents/show.html.erb create mode 100644 app/views/enumerations/_form.html.erb create mode 100644 app/views/enumerations/destroy.html.erb create mode 100644 app/views/enumerations/edit.html.erb create mode 100644 app/views/enumerations/index.api.rsb create mode 100644 app/views/enumerations/index.html.erb create mode 100644 app/views/enumerations/new.html.erb create mode 100644 app/views/files/index.html.erb create mode 100644 app/views/files/new.html.erb create mode 100644 app/views/gantts/show.html.erb create mode 100644 app/views/groups/_form.html.erb create mode 100644 app/views/groups/_general.html.erb create mode 100644 app/views/groups/_memberships.html.erb create mode 100644 app/views/groups/_users.html.erb create mode 100644 app/views/groups/add_users.js.erb create mode 100644 app/views/groups/autocomplete_for_user.js.erb create mode 100644 app/views/groups/destroy_membership.js.erb create mode 100644 app/views/groups/edit.html.erb create mode 100644 app/views/groups/edit_membership.js.erb create mode 100644 app/views/groups/index.api.rsb create mode 100644 app/views/groups/index.html.erb create mode 100644 app/views/groups/new.html.erb create mode 100644 app/views/groups/remove_user.js.erb create mode 100644 app/views/groups/show.api.rsb create mode 100644 app/views/groups/show.html.erb create mode 100644 app/views/issue_categories/_form.html.erb create mode 100644 app/views/issue_categories/_new_modal.html.erb create mode 100644 app/views/issue_categories/create.js.erb create mode 100644 app/views/issue_categories/destroy.html.erb create mode 100644 app/views/issue_categories/edit.html.erb create mode 100644 app/views/issue_categories/index.api.rsb create mode 100644 app/views/issue_categories/new.html.erb create mode 100644 app/views/issue_categories/new.js.erb create mode 100644 app/views/issue_categories/show.api.rsb create mode 100644 app/views/issue_relations/_form.html.erb create mode 100644 app/views/issue_relations/create.js.erb create mode 100644 app/views/issue_relations/destroy.js.erb create mode 100644 app/views/issue_relations/index.api.rsb create mode 100644 app/views/issue_relations/show.api.rsb create mode 100644 app/views/issue_statuses/_form.html.erb create mode 100644 app/views/issue_statuses/edit.html.erb create mode 100644 app/views/issue_statuses/index.api.rsb create mode 100644 app/views/issue_statuses/index.html.erb create mode 100644 app/views/issue_statuses/new.html.erb create mode 100644 app/views/issues/_action_menu.html.erb create mode 100644 app/views/issues/_attributes.html.erb create mode 100644 app/views/issues/_changesets.html.erb create mode 100644 app/views/issues/_conflict.html.erb create mode 100644 app/views/issues/_edit.html.erb create mode 100644 app/views/issues/_form.html.erb create mode 100644 app/views/issues/_form_custom_fields.html.erb create mode 100644 app/views/issues/_history.html.erb create mode 100644 app/views/issues/_list.html.erb create mode 100644 app/views/issues/_list_simple.html.erb create mode 100644 app/views/issues/_relations.html.erb create mode 100644 app/views/issues/_sidebar.html.erb create mode 100644 app/views/issues/bulk_edit.html.erb create mode 100644 app/views/issues/bulk_edit.js.erb create mode 100644 app/views/issues/destroy.html.erb create mode 100644 app/views/issues/edit.html.erb create mode 100644 app/views/issues/index.api.rsb create mode 100644 app/views/issues/index.html.erb create mode 100644 app/views/issues/new.html.erb create mode 100644 app/views/issues/show.api.rsb create mode 100644 app/views/issues/show.html.erb create mode 100644 app/views/issues/update_form.js.erb create mode 100644 app/views/journals/_notes_form.html.erb create mode 100644 app/views/journals/diff.html.erb create mode 100644 app/views/journals/edit.js.erb create mode 100644 app/views/journals/index.builder create mode 100644 app/views/journals/new.js.erb create mode 100644 app/views/journals/update.js.erb create mode 100644 app/views/layouts/_base_header.html.erb create mode 100644 app/views/layouts/_tag.html.erb create mode 100644 app/views/layouts/_tag_name.html.erb create mode 100644 app/views/layouts/admin.html.erb create mode 100644 app/views/layouts/base.html.erb create mode 100644 app/views/layouts/base.html_old.erb create mode 100644 app/views/layouts/base_.html.erb create mode 100644 app/views/layouts/base_bids.html.erb create mode 100644 app/views/layouts/base_old.html.erb create mode 100644 app/views/layouts/base_projects.html.erb create mode 100644 app/views/layouts/base_users.html.erb create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100644 app/views/list/members.html.erb create mode 100644 app/views/mailer/_issue.html.erb create mode 100644 app/views/mailer/_issue.text.erb create mode 100644 app/views/mailer/account_activated.html.erb create mode 100644 app/views/mailer/account_activated.text.erb create mode 100644 app/views/mailer/account_activation_request.html.erb create mode 100644 app/views/mailer/account_activation_request.text.erb create mode 100644 app/views/mailer/account_information.html.erb create mode 100644 app/views/mailer/account_information.text.erb create mode 100644 app/views/mailer/attachments_added.html.erb create mode 100644 app/views/mailer/attachments_added.text.erb create mode 100644 app/views/mailer/document_added.html.erb create mode 100644 app/views/mailer/document_added.text.erb create mode 100644 app/views/mailer/issue_add.html.erb create mode 100644 app/views/mailer/issue_add.text.erb create mode 100644 app/views/mailer/issue_edit.html.erb create mode 100644 app/views/mailer/issue_edit.text.erb create mode 100644 app/views/mailer/lost_password.html.erb create mode 100644 app/views/mailer/lost_password.text.erb create mode 100644 app/views/mailer/message_posted.html.erb create mode 100644 app/views/mailer/message_posted.text.erb create mode 100644 app/views/mailer/news_added.html.erb create mode 100644 app/views/mailer/news_added.text.erb create mode 100644 app/views/mailer/news_comment_added.html.erb create mode 100644 app/views/mailer/news_comment_added.text.erb create mode 100644 app/views/mailer/register.html.erb create mode 100644 app/views/mailer/register.text.erb create mode 100644 app/views/mailer/reminder.html.erb create mode 100644 app/views/mailer/reminder.text.erb create mode 100644 app/views/mailer/test_email.html.erb create mode 100644 app/views/mailer/test_email.text.erb create mode 100644 app/views/mailer/wiki_content_added.html.erb create mode 100644 app/views/mailer/wiki_content_added.text.erb create mode 100644 app/views/mailer/wiki_content_updated.html.erb create mode 100644 app/views/mailer/wiki_content_updated.text.erb create mode 100644 app/views/members/autocomplete.js.erb create mode 100644 app/views/members/create.js.erb create mode 100644 app/views/members/destroy.js.erb create mode 100644 app/views/members/index.api.rsb create mode 100644 app/views/members/show.api.rsb create mode 100644 app/views/members/update.js.erb create mode 100644 app/views/messages/_form.html.erb create mode 100644 app/views/messages/edit.html.erb create mode 100644 app/views/messages/new.html.erb create mode 100644 app/views/messages/quote.js.erb create mode 100644 app/views/messages/show.html.erb create mode 100644 app/views/my/_block.html.erb create mode 100644 app/views/my/_sidebar.html.erb create mode 100644 app/views/my/account.html.erb create mode 100644 app/views/my/blocks/_calendar.html.erb create mode 100644 app/views/my/blocks/_documents.html.erb create mode 100644 app/views/my/blocks/_issuesassignedtome.html.erb create mode 100644 app/views/my/blocks/_issuesreportedbyme.html.erb create mode 100644 app/views/my/blocks/_issueswatched.html.erb create mode 100644 app/views/my/blocks/_news.html.erb create mode 100644 app/views/my/blocks/_timelog.html.erb create mode 100644 app/views/my/destroy.html.erb create mode 100644 app/views/my/page.html.erb create mode 100644 app/views/my/page_layout.html.erb create mode 100644 app/views/my/password.html.erb create mode 100644 app/views/news/_form.html.erb create mode 100644 app/views/news/_news.html.erb create mode 100644 app/views/news/edit.html.erb create mode 100644 app/views/news/index.api.rsb create mode 100644 app/views/news/index.html.erb create mode 100644 app/views/news/new.html.erb create mode 100644 app/views/news/show.html.erb create mode 100644 app/views/newsold/_form.html.erb create mode 100644 app/views/newsold/_news.html.erb create mode 100644 app/views/newsold/edit.html.erb create mode 100644 app/views/newsold/index.api.rsb create mode 100644 app/views/newsold/index.html.erb create mode 100644 app/views/newsold/new.html.erb create mode 100644 app/views/newsold/show.html.erb create mode 100644 app/views/previews/issue.html.erb create mode 100644 app/views/projects/Copy of show.html.erb create mode 100644 app/views/projects/_edit.html.erb create mode 100644 app/views/projects/_form.html.erb create mode 100644 app/views/projects/_members_box.html.erb create mode 100644 app/views/projects/_project.html.erb create mode 100644 app/views/projects/copy.html.erb create mode 100644 app/views/projects/destroy.html.erb create mode 100644 app/views/projects/file.html.erb create mode 100644 app/views/projects/focus.html.erb create mode 100644 app/views/projects/index.api.rsb create mode 100644 app/views/projects/index.html.erb create mode 100644 app/views/projects/investor.html.erb create mode 100644 app/views/projects/issue.html.erb create mode 100644 app/views/projects/list_members.html.erb create mode 100644 app/views/projects/member.html.erb create mode 100644 app/views/projects/mission.html.erb create mode 100644 app/views/projects/new.html.erb create mode 100644 app/views/projects/on.html.erb create mode 100644 app/views/projects/settings.html.erb create mode 100644 app/views/projects/settings/_activities.html.erb create mode 100644 app/views/projects/settings/_boards.html.erb create mode 100644 app/views/projects/settings/_issue_categories.html.erb create mode 100644 app/views/projects/settings/_members.html.erb create mode 100644 app/views/projects/settings/_modules.html.erb create mode 100644 app/views/projects/settings/_repositories.html.erb create mode 100644 app/views/projects/settings/_versions.html.erb create mode 100644 app/views/projects/settings/_wiki.html.erb create mode 100644 app/views/projects/show-old.html.erb create mode 100644 app/views/projects/show.api.rsb create mode 100644 app/views/projects/show.html.erb create mode 100644 app/views/projects/show_new.html.erb create mode 100644 app/views/queries/_columns.html.erb create mode 100644 app/views/queries/_filters.html.erb create mode 100644 app/views/queries/_form.html.erb create mode 100644 app/views/queries/edit.html.erb create mode 100644 app/views/queries/index.api.rsb create mode 100644 app/views/queries/index.html.erb create mode 100644 app/views/queries/new.html.erb create mode 100644 app/views/reports/_details.html.erb create mode 100644 app/views/reports/_simple.html.erb create mode 100644 app/views/reports/issue_report.html.erb create mode 100644 app/views/reports/issue_report_details.html.erb create mode 100644 app/views/repositories/_breadcrumbs.html.erb create mode 100644 app/views/repositories/_dir_list.html.erb create mode 100644 app/views/repositories/_dir_list_content.html.erb create mode 100644 app/views/repositories/_form.html.erb create mode 100644 app/views/repositories/_link_to_functions.html.erb create mode 100644 app/views/repositories/_navigation.html.erb create mode 100644 app/views/repositories/_related_issues.html.erb create mode 100644 app/views/repositories/_revision_graph.html.erb create mode 100644 app/views/repositories/_revisions.html.erb create mode 100644 app/views/repositories/add_related_issue.js.erb create mode 100644 app/views/repositories/annotate.html.erb create mode 100644 app/views/repositories/changes.html.erb create mode 100644 app/views/repositories/committers.html.erb create mode 100644 app/views/repositories/diff.html.erb create mode 100644 app/views/repositories/edit.html.erb create mode 100644 app/views/repositories/entry.html.erb create mode 100644 app/views/repositories/new.html.erb create mode 100644 app/views/repositories/new.js.erb create mode 100644 app/views/repositories/remove_related_issue.js.erb create mode 100644 app/views/repositories/revision.html.erb create mode 100644 app/views/repositories/revisions.html.erb create mode 100644 app/views/repositories/show.html.erb create mode 100644 app/views/repositories/stats.html.erb create mode 100644 app/views/roles/_form.html.erb create mode 100644 app/views/roles/edit.html.erb create mode 100644 app/views/roles/index.api.rsb create mode 100644 app/views/roles/index.html.erb create mode 100644 app/views/roles/new.html.erb create mode 100644 app/views/roles/permissions.html.erb create mode 100644 app/views/roles/show.api.rsb create mode 100644 app/views/search/index.html.erb create mode 100644 app/views/settings/_authentication.html.erb create mode 100644 app/views/settings/_display.html.erb create mode 100644 app/views/settings/_general.html.erb create mode 100644 app/views/settings/_issues.html.erb create mode 100644 app/views/settings/_mail_handler.html.erb create mode 100644 app/views/settings/_notifications.html.erb create mode 100644 app/views/settings/_projects.html.erb create mode 100644 app/views/settings/_repositories.html.erb create mode 100644 app/views/settings/edit.html.erb create mode 100644 app/views/settings/plugin.html.erb create mode 100644 app/views/tags/_related_tags.html.erb create mode 100644 app/views/tags/_selected_tags.html.erb create mode 100644 app/views/tags/_show_results.html.erb create mode 100644 app/views/tags/_tag_search_results.html.erb create mode 100644 app/views/tags/add_tag.js.erb create mode 100644 app/views/tags/delete_tag.js.erb create mode 100644 app/views/tags/index.html.erb create mode 100644 app/views/test/_message.html.erb create mode 100644 app/views/test/_new.html.erb create mode 100644 app/views/test/create.js.erb create mode 100644 app/views/test/destroy.js.erb create mode 100644 app/views/test/index.html.erb create mode 100644 app/views/test/new.js.erb create mode 100644 app/views/timelog/_date_range.html.erb create mode 100644 app/views/timelog/_form.html.erb create mode 100644 app/views/timelog/_list.html.erb create mode 100644 app/views/timelog/_report_criteria.html.erb create mode 100644 app/views/timelog/bulk_edit.html.erb create mode 100644 app/views/timelog/edit.html.erb create mode 100644 app/views/timelog/index.api.rsb create mode 100644 app/views/timelog/index.html.erb create mode 100644 app/views/timelog/new.html.erb create mode 100644 app/views/timelog/report.html.erb create mode 100644 app/views/timelog/show.api.rsb create mode 100644 app/views/trackers/_form.html.erb create mode 100644 app/views/trackers/edit.html.erb create mode 100644 app/views/trackers/fields.html.erb create mode 100644 app/views/trackers/index.api.rsb create mode 100644 app/views/trackers/index.html.erb create mode 100644 app/views/trackers/new.html.erb create mode 100644 app/views/users/_form.html.erb create mode 100644 app/views/users/_general.html.erb create mode 100644 app/views/users/_groups.html.erb create mode 100644 app/views/users/_leave_message.html.erb create mode 100644 app/views/users/_mail_notifications.html.erb create mode 100644 app/views/users/_memberships.html.erb create mode 100644 app/views/users/_preferences.html.erb create mode 100644 app/views/users/blocks/_calendar.html.erb create mode 100644 app/views/users/blocks/_issuesassignedtome.html.erb create mode 100644 app/views/users/destroy_membership.js.erb create mode 100644 app/views/users/edit.html.erb create mode 100644 app/views/users/edit_membership.js.erb create mode 100644 app/views/users/index.api.rsb create mode 100644 app/views/users/index.html.erb create mode 100644 app/views/users/leave_message.js.erb create mode 100644 app/views/users/list.api.rsb create mode 100644 app/views/users/list.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/show.api.rsb create mode 100644 app/views/users/show.html.erb create mode 100644 app/views/users/show_old.html.erb create mode 100644 app/views/users/tag_save.js.erb create mode 100644 app/views/users/user_activities.html.erb create mode 100644 app/views/users/user_comments.html.erb create mode 100644 app/views/users/user_newfeedback.html.erb create mode 100644 app/views/users/user_projects.html.erb create mode 100644 app/views/versions/_form.html.erb create mode 100644 app/views/versions/_issue_counts.html.erb create mode 100644 app/views/versions/_new_modal.html.erb create mode 100644 app/views/versions/_overview.html.erb create mode 100644 app/views/versions/create.js.erb create mode 100644 app/views/versions/edit.html.erb create mode 100644 app/views/versions/index.api.rsb create mode 100644 app/views/versions/index.html.erb create mode 100644 app/views/versions/new.html.erb create mode 100644 app/views/versions/new.js.erb create mode 100644 app/views/versions/show.api.rsb create mode 100644 app/views/versions/show.html.erb create mode 100644 app/views/versions/status_by.js.erb create mode 100644 app/views/watchers/_new.html.erb create mode 100644 app/views/watchers/_set_watcher.js.erb create mode 100644 app/views/watchers/_watchers.html.erb create mode 100644 app/views/watchers/append.js.erb create mode 100644 app/views/watchers/autocomplete_for_user.html.erb create mode 100644 app/views/watchers/create.js.erb create mode 100644 app/views/watchers/destroy.js.erb create mode 100644 app/views/watchers/new.js.erb create mode 100644 app/views/welcome/index.html.erb create mode 100644 app/views/welcome/robots.html.erb create mode 100644 app/views/wiki/_content.html.erb create mode 100644 app/views/wiki/_sidebar.html.erb create mode 100644 app/views/wiki/annotate.html.erb create mode 100644 app/views/wiki/date_index.html.erb create mode 100644 app/views/wiki/destroy.html.erb create mode 100644 app/views/wiki/diff.html.erb create mode 100644 app/views/wiki/edit.html.erb create mode 100644 app/views/wiki/export.html.erb create mode 100644 app/views/wiki/export_multiple.html.erb create mode 100644 app/views/wiki/history.html.erb create mode 100644 app/views/wiki/index.api.rsb create mode 100644 app/views/wiki/index.html.erb create mode 100644 app/views/wiki/rename.html.erb create mode 100644 app/views/wiki/show.api.rsb create mode 100644 app/views/wiki/show.html.erb create mode 100644 app/views/wikis/destroy.html.erb create mode 100644 app/views/wikis/edit.js.erb create mode 100644 app/views/words/_message.html.erb create mode 100644 app/views/words/_new.html.erb create mode 100644 app/views/words/back.js.erb create mode 100644 app/views/words/create.js.erb create mode 100644 app/views/words/destroy.js.erb create mode 100644 app/views/words/more.js.erb create mode 100644 app/views/words/new.js.erb create mode 100644 app/views/workflows/_action_menu.html.erb create mode 100644 app/views/workflows/_form.html.erb create mode 100644 app/views/workflows/copy.html.erb create mode 100644 app/views/workflows/edit.html.erb create mode 100644 app/views/workflows/index.html.erb create mode 100644 app/views/workflows/permissions.html.erb create mode 100644 config.ru create mode 100644 config/additional_environment.rb create mode 100644 config/additional_environment.rb.example create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/configuration.yml create mode 100644 config/configuration.yml.example create mode 100644 config/database.yml create mode 100644 config/database.yml.example create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/environments/test_pgsql.rb create mode 100644 config/environments/test_sqlite3.rb create mode 100644 config/initializers/00-core_plugins.rb create mode 100644 config/initializers/10-patches.rb create mode 100644 config/initializers/20-mime_types.rb create mode 100644 config/initializers/30-redmine.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/secret_token.rb create mode 100644 config/locales/ar.yml create mode 100644 config/locales/az.yml create mode 100644 config/locales/bg.yml create mode 100644 config/locales/bs.yml create mode 100644 config/locales/ca.yml create mode 100644 config/locales/cs.yml create mode 100644 config/locales/da.yml create mode 100644 config/locales/de.yml create mode 100644 config/locales/el.yml create mode 100644 config/locales/en-GB.yml create mode 100644 config/locales/en.yml create mode 100644 config/locales/es.yml create mode 100644 config/locales/et.yml create mode 100644 config/locales/eu.yml create mode 100644 config/locales/fa.yml create mode 100644 config/locales/fi.yml create mode 100644 config/locales/fr.yml create mode 100644 config/locales/gl.yml create mode 100644 config/locales/he.yml create mode 100644 config/locales/hr.yml create mode 100644 config/locales/hu.yml create mode 100644 config/locales/id.yml create mode 100644 config/locales/it.yml create mode 100644 config/locales/ja.yml create mode 100644 config/locales/ko.yml create mode 100644 config/locales/lt.yml create mode 100644 config/locales/lv.yml create mode 100644 config/locales/mk.yml create mode 100644 config/locales/mn.yml create mode 100644 config/locales/nl.yml create mode 100644 config/locales/no.yml create mode 100644 config/locales/pl.yml create mode 100644 config/locales/pt-BR.yml create mode 100644 config/locales/pt.yml create mode 100644 config/locales/ro.yml create mode 100644 config/locales/ru.yml create mode 100644 config/locales/sk.yml create mode 100644 config/locales/sl.yml create mode 100644 config/locales/sq.yml create mode 100644 config/locales/sr-YU.yml create mode 100644 config/locales/sr.yml create mode 100644 config/locales/sv.yml create mode 100644 config/locales/th.yml create mode 100644 config/locales/tr.yml create mode 100644 config/locales/uk.yml create mode 100644 config/locales/vi.yml create mode 100644 config/locales/zh-TW.yml create mode 100644 config/locales/zh.yml create mode 100644 config/preinitializer.rb create mode 100644 config/routes.rb create mode 100644 config/settings.yml create mode 100644 db/development.sqlite3 create mode 100644 db/migrate/001_setup.rb create mode 100644 db/migrate/002_issue_move.rb create mode 100644 db/migrate/003_issue_add_note.rb create mode 100644 db/migrate/004_export_pdf.rb create mode 100644 db/migrate/005_issue_start_date.rb create mode 100644 db/migrate/006_calendar_and_activity.rb create mode 100644 db/migrate/007_create_journals.rb create mode 100644 db/migrate/008_create_user_preferences.rb create mode 100644 db/migrate/009_add_hide_mail_pref.rb create mode 100644 db/migrate/010_create_comments.rb create mode 100644 db/migrate/011_add_news_comments_count.rb create mode 100644 db/migrate/012_add_comments_permissions.rb create mode 100644 db/migrate/013_create_queries.rb create mode 100644 db/migrate/014_add_queries_permissions.rb create mode 100644 db/migrate/015_create_repositories.rb create mode 100644 db/migrate/016_add_repositories_permissions.rb create mode 100644 db/migrate/017_create_settings.rb create mode 100644 db/migrate/018_set_doc_and_files_notifications.rb create mode 100644 db/migrate/019_add_issue_status_position.rb create mode 100644 db/migrate/020_add_role_position.rb create mode 100644 db/migrate/021_add_tracker_position.rb create mode 100644 db/migrate/022_serialize_possibles_values.rb create mode 100644 db/migrate/023_add_tracker_is_in_roadmap.rb create mode 100644 db/migrate/024_add_roadmap_permission.rb create mode 100644 db/migrate/025_add_search_permission.rb create mode 100644 db/migrate/026_add_repository_login_and_password.rb create mode 100644 db/migrate/027_create_wikis.rb create mode 100644 db/migrate/028_create_wiki_pages.rb create mode 100644 db/migrate/029_create_wiki_contents.rb create mode 100644 db/migrate/030_add_projects_feeds_permissions.rb create mode 100644 db/migrate/031_add_repository_root_url.rb create mode 100644 db/migrate/032_create_time_entries.rb create mode 100644 db/migrate/033_add_timelog_permissions.rb create mode 100644 db/migrate/034_create_changesets.rb create mode 100644 db/migrate/035_create_changes.rb create mode 100644 db/migrate/036_add_changeset_commit_date.rb create mode 100644 db/migrate/037_add_project_identifier.rb create mode 100644 db/migrate/038_add_custom_field_is_filter.rb create mode 100644 db/migrate/039_create_watchers.rb create mode 100644 db/migrate/040_create_changesets_issues.rb create mode 100644 db/migrate/041_rename_comment_to_comments.rb create mode 100644 db/migrate/042_create_issue_relations.rb create mode 100644 db/migrate/043_add_relations_permissions.rb create mode 100644 db/migrate/044_set_language_length_to_five.rb create mode 100644 db/migrate/045_create_boards.rb create mode 100644 db/migrate/046_create_messages.rb create mode 100644 db/migrate/047_add_boards_permissions.rb create mode 100644 db/migrate/048_allow_null_version_effective_date.rb create mode 100644 db/migrate/049_add_wiki_destroy_page_permission.rb create mode 100644 db/migrate/050_add_wiki_attachments_permissions.rb create mode 100644 db/migrate/051_add_project_status.rb create mode 100644 db/migrate/052_add_changes_revision.rb create mode 100644 db/migrate/053_add_changes_branch.rb create mode 100644 db/migrate/054_add_changesets_scmid.rb create mode 100644 db/migrate/055_add_repositories_type.rb create mode 100644 db/migrate/056_add_repositories_changes_permission.rb create mode 100644 db/migrate/057_add_versions_wiki_page_title.rb create mode 100644 db/migrate/058_add_issue_categories_assigned_to_id.rb create mode 100644 db/migrate/059_add_roles_assignable.rb create mode 100644 db/migrate/060_change_changesets_committer_limit.rb create mode 100644 db/migrate/061_add_roles_builtin.rb create mode 100644 db/migrate/062_insert_builtin_roles.rb create mode 100644 db/migrate/063_add_roles_permissions.rb create mode 100644 db/migrate/064_drop_permissions.rb create mode 100644 db/migrate/065_add_settings_updated_on.rb create mode 100644 db/migrate/066_add_custom_value_customized_index.rb create mode 100644 db/migrate/067_create_wiki_redirects.rb create mode 100644 db/migrate/068_create_enabled_modules.rb create mode 100644 db/migrate/069_add_issues_estimated_hours.rb create mode 100644 db/migrate/070_change_attachments_content_type_limit.rb create mode 100644 db/migrate/071_add_queries_column_names.rb create mode 100644 db/migrate/072_add_enumerations_position.rb create mode 100644 db/migrate/073_add_enumerations_is_default.rb create mode 100644 db/migrate/074_add_auth_sources_tls.rb create mode 100644 db/migrate/075_add_members_mail_notification.rb create mode 100644 db/migrate/076_allow_null_position.rb create mode 100644 db/migrate/077_remove_issue_statuses_html_color.rb create mode 100644 db/migrate/078_add_custom_fields_position.rb create mode 100644 db/migrate/079_add_user_preferences_time_zone.rb create mode 100644 db/migrate/080_add_users_type.rb create mode 100644 db/migrate/081_create_projects_trackers.rb create mode 100644 db/migrate/082_add_messages_locked.rb create mode 100644 db/migrate/083_add_messages_sticky.rb create mode 100644 db/migrate/084_change_auth_sources_account_limit.rb create mode 100644 db/migrate/085_add_role_tracker_old_status_index_to_workflows.rb create mode 100644 db/migrate/086_add_custom_fields_searchable.rb create mode 100644 db/migrate/087_change_projects_description_to_text.rb create mode 100644 db/migrate/088_add_custom_fields_default_value.rb create mode 100644 db/migrate/089_add_attachments_description.rb create mode 100644 db/migrate/090_change_versions_name_limit.rb create mode 100644 db/migrate/091_change_changesets_revision_to_string.rb create mode 100644 db/migrate/092_change_changes_from_revision_to_string.rb create mode 100644 db/migrate/093_add_wiki_pages_protected.rb create mode 100644 db/migrate/094_change_projects_homepage_limit.rb create mode 100644 db/migrate/095_add_wiki_pages_parent_id.rb create mode 100644 db/migrate/096_add_commit_access_permission.rb create mode 100644 db/migrate/097_add_view_wiki_edits_permission.rb create mode 100644 db/migrate/098_set_topic_authors_as_watchers.rb create mode 100644 db/migrate/099_add_delete_wiki_pages_attachments_permission.rb create mode 100644 db/migrate/100_add_changesets_user_id.rb create mode 100644 db/migrate/101_populate_changesets_user_id.rb create mode 100644 db/migrate/102_add_custom_fields_editable.rb create mode 100644 db/migrate/103_set_custom_fields_editable.rb create mode 100644 db/migrate/104_add_projects_lft_and_rgt.rb create mode 100644 db/migrate/105_build_projects_tree.rb create mode 100644 db/migrate/106_remove_projects_projects_count.rb create mode 100644 db/migrate/107_add_open_id_authentication_tables.rb create mode 100644 db/migrate/108_add_identity_url_to_users.rb create mode 100644 db/migrate/20090214190337_add_watchers_user_id_type_index.rb create mode 100644 db/migrate/20090312172426_add_queries_sort_criteria.rb create mode 100644 db/migrate/20090312194159_add_projects_trackers_unique_index.rb create mode 100644 db/migrate/20090318181151_extend_settings_name.rb create mode 100644 db/migrate/20090323224724_add_type_to_enumerations.rb create mode 100644 db/migrate/20090401221305_update_enumerations_to_sti.rb create mode 100644 db/migrate/20090401231134_add_active_field_to_enumerations.rb create mode 100644 db/migrate/20090403001910_add_project_to_enumerations.rb create mode 100644 db/migrate/20090406161854_add_parent_id_to_enumerations.rb create mode 100644 db/migrate/20090425161243_add_queries_group_by.rb create mode 100644 db/migrate/20090503121501_create_member_roles.rb create mode 100644 db/migrate/20090503121505_populate_member_roles.rb create mode 100644 db/migrate/20090503121510_drop_members_role_id.rb create mode 100644 db/migrate/20090614091200_fix_messages_sticky_null.rb create mode 100644 db/migrate/20090704172350_populate_users_type.rb create mode 100644 db/migrate/20090704172355_create_groups_users.rb create mode 100644 db/migrate/20090704172358_add_member_roles_inherited_from.rb create mode 100644 db/migrate/20091010093521_fix_users_custom_values.rb create mode 100644 db/migrate/20091017212227_add_missing_indexes_to_workflows.rb create mode 100644 db/migrate/20091017212457_add_missing_indexes_to_custom_fields_projects.rb create mode 100644 db/migrate/20091017212644_add_missing_indexes_to_messages.rb create mode 100644 db/migrate/20091017212938_add_missing_indexes_to_repositories.rb create mode 100644 db/migrate/20091017213027_add_missing_indexes_to_comments.rb create mode 100644 db/migrate/20091017213113_add_missing_indexes_to_enumerations.rb create mode 100644 db/migrate/20091017213151_add_missing_indexes_to_wiki_pages.rb create mode 100644 db/migrate/20091017213228_add_missing_indexes_to_watchers.rb create mode 100644 db/migrate/20091017213257_add_missing_indexes_to_auth_sources.rb create mode 100644 db/migrate/20091017213332_add_missing_indexes_to_documents.rb create mode 100644 db/migrate/20091017213444_add_missing_indexes_to_tokens.rb create mode 100644 db/migrate/20091017213536_add_missing_indexes_to_changesets.rb create mode 100644 db/migrate/20091017213642_add_missing_indexes_to_issue_categories.rb create mode 100644 db/migrate/20091017213716_add_missing_indexes_to_member_roles.rb create mode 100644 db/migrate/20091017213757_add_missing_indexes_to_boards.rb create mode 100644 db/migrate/20091017213835_add_missing_indexes_to_user_preferences.rb create mode 100644 db/migrate/20091017213910_add_missing_indexes_to_issues.rb create mode 100644 db/migrate/20091017214015_add_missing_indexes_to_members.rb create mode 100644 db/migrate/20091017214107_add_missing_indexes_to_custom_fields.rb create mode 100644 db/migrate/20091017214136_add_missing_indexes_to_queries.rb create mode 100644 db/migrate/20091017214236_add_missing_indexes_to_time_entries.rb create mode 100644 db/migrate/20091017214308_add_missing_indexes_to_news.rb create mode 100644 db/migrate/20091017214336_add_missing_indexes_to_users.rb create mode 100644 db/migrate/20091017214406_add_missing_indexes_to_attachments.rb create mode 100644 db/migrate/20091017214440_add_missing_indexes_to_wiki_contents.rb create mode 100644 db/migrate/20091017214519_add_missing_indexes_to_custom_values.rb create mode 100644 db/migrate/20091017214611_add_missing_indexes_to_journals.rb create mode 100644 db/migrate/20091017214644_add_missing_indexes_to_issue_relations.rb create mode 100644 db/migrate/20091017214720_add_missing_indexes_to_wiki_redirects.rb create mode 100644 db/migrate/20091017214750_add_missing_indexes_to_custom_fields_trackers.rb create mode 100644 db/migrate/20091025163651_add_activity_indexes.rb create mode 100644 db/migrate/20091108092559_add_versions_status.rb create mode 100644 db/migrate/20091114105931_add_view_issues_permission.rb create mode 100644 db/migrate/20091123212029_add_default_done_ratio_to_issue_status.rb create mode 100644 db/migrate/20091205124427_add_versions_sharing.rb create mode 100644 db/migrate/20091220183509_add_lft_and_rgt_indexes_to_projects.rb create mode 100644 db/migrate/20091220183727_add_index_to_settings_name.rb create mode 100644 db/migrate/20091220184736_add_indexes_to_issue_status.rb create mode 100644 db/migrate/20091225164732_remove_enumerations_opt.rb create mode 100644 db/migrate/20091227112908_change_wiki_contents_text_limit.rb create mode 100644 db/migrate/20100129193402_change_users_mail_notification_to_string.rb create mode 100644 db/migrate/20100129193813_update_mail_notification_values.rb create mode 100644 db/migrate/20100221100219_add_index_on_changesets_scmid.rb create mode 100644 db/migrate/20100313132032_add_issues_nested_sets_columns.rb create mode 100644 db/migrate/20100313171051_add_index_on_issues_nested_set.rb create mode 100644 db/migrate/20100705164950_change_changes_path_length_limit.rb create mode 100644 db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb create mode 100644 db/migrate/20101104182107_add_unique_index_on_members.rb create mode 100644 db/migrate/20101107130441_add_custom_fields_visible.rb create mode 100644 db/migrate/20101114115114_change_projects_name_limit.rb create mode 100644 db/migrate/20101114115359_change_projects_identifier_limit.rb create mode 100644 db/migrate/20110220160626_add_workflows_assignee_and_author.rb create mode 100644 db/migrate/20110223180944_add_users_salt.rb create mode 100644 db/migrate/20110223180953_salt_user_passwords.rb create mode 100644 db/migrate/20110224000000_add_repositories_path_encoding.rb create mode 100644 db/migrate/20110226120112_change_repositories_password_limit.rb create mode 100644 db/migrate/20110226120132_change_auth_sources_account_password_limit.rb create mode 100644 db/migrate/20110227125750_change_journal_details_values_to_text.rb create mode 100644 db/migrate/20110228000000_add_repositories_log_encoding.rb create mode 100644 db/migrate/20110228000100_copy_repositories_log_encoding.rb create mode 100644 db/migrate/20110401192910_add_index_to_users_type.rb create mode 100644 db/migrate/20110408103312_add_roles_issues_visibility.rb create mode 100644 db/migrate/20110412065600_add_issues_is_private.rb create mode 100644 db/migrate/20110511000000_add_repositories_extra_info.rb create mode 100644 db/migrate/20110902000000_create_changeset_parents.rb create mode 100644 db/migrate/20111201201315_add_unique_index_to_issue_relations.rb create mode 100644 db/migrate/20120115143024_add_repositories_identifier.rb create mode 100644 db/migrate/20120115143100_add_repositories_is_default.rb create mode 100644 db/migrate/20120115143126_set_default_repositories.rb create mode 100644 db/migrate/20120127174243_add_custom_fields_multiple.rb create mode 100644 db/migrate/20120205111326_change_users_login_limit.rb create mode 100644 db/migrate/20120223110929_change_attachments_container_defaults.rb create mode 100644 db/migrate/20120301153455_add_auth_sources_filter.rb create mode 100644 db/migrate/20120422150750_change_repositories_to_full_sti.rb create mode 100644 db/migrate/20120705074331_add_trackers_fields_bits.rb create mode 100644 db/migrate/20120707064544_add_auth_sources_timeout.rb create mode 100644 db/migrate/20120714122000_add_workflows_type.rb create mode 100644 db/migrate/20120714122100_update_workflows_to_sti.rb create mode 100644 db/migrate/20120714122200_add_workflows_rule_fields.rb create mode 100644 db/migrate/20120731164049_add_boards_parent_id.rb create mode 100644 db/migrate/20120930112914_add_journals_private_notes.rb create mode 100644 db/migrate/20121026002032_add_enumerations_position_name.rb create mode 100644 db/migrate/20121026003537_populate_enumerations_position_name.rb create mode 100644 db/migrate/20121209123234_add_queries_type.rb create mode 100644 db/migrate/20121209123358_update_queries_to_sti.rb create mode 100644 db/migrate/20121213084931_add_attachments_disk_directory.rb create mode 100644 db/migrate/20130110122628_split_documents_permissions.rb create mode 100644 db/migrate/20130201184705_add_unique_index_on_tokens_value.rb create mode 100644 db/migrate/20130202090625_add_projects_inherit_members.rb create mode 100644 db/migrate/20130207175206_add_unique_index_on_custom_fields_trackers.rb create mode 100644 db/migrate/20130207181455_add_unique_index_on_custom_fields_projects.rb create mode 100644 db/migrate/20130215073721_change_users_lastname_length_to_255.rb create mode 100644 db/migrate/20130215111127_add_issues_closed_on.rb create mode 100644 db/migrate/20130215111141_populate_issues_closed_on.rb create mode 100644 db/migrate/20130217094251_remove_issues_default_fk_values.rb create mode 100644 db/migrate/20130725021433_acts_as_taggable_on_migration.rb create mode 100644 db/migrate/20130725122407_create_bids.rb create mode 100644 db/migrate/20130725132508_create_biding_projects.rb create mode 100644 db/migrate/20130727021306_create_journals_for_messages.rb create mode 100644 db/migrate/20130728021709_add_commit_to_bids.rb create mode 100644 db/schema.rb create mode 100644 doc/CHANGELOG create mode 100644 doc/COPYING create mode 100644 doc/INSTALL create mode 100644 doc/README_FOR_APP create mode 100644 doc/RUNNING_TESTS create mode 100644 doc/UPGRADING create mode 100644 extra/mail_handler/rdm-mailhandler.rb create mode 100644 extra/sample_plugin/README create mode 100644 extra/sample_plugin/app/controllers/example_controller.rb create mode 100644 extra/sample_plugin/app/models/meeting.rb create mode 100644 extra/sample_plugin/app/views/example/say_goodbye.html.erb create mode 100644 extra/sample_plugin/app/views/example/say_hello.html.erb create mode 100644 extra/sample_plugin/app/views/my/blocks/_sample_block.html.erb create mode 100644 extra/sample_plugin/app/views/settings/_sample_plugin_settings.html.erb create mode 100644 extra/sample_plugin/assets/images/it_works.png create mode 100644 extra/sample_plugin/assets/stylesheets/example.css create mode 100644 extra/sample_plugin/config/locales/en.yml create mode 100644 extra/sample_plugin/config/locales/fr.yml create mode 100644 extra/sample_plugin/config/routes.rb create mode 100644 extra/sample_plugin/db/migrate/001_create_meetings.rb create mode 100644 extra/sample_plugin/init.rb create mode 100644 extra/sample_plugin/test/integration/routing_test.rb create mode 100644 extra/svn/Redmine.pm create mode 100644 extra/svn/reposman.rb create mode 100644 files/2013/07/130722111340_2f0b01a362fe0cdd98bbadd22ea6e1cc.pptx create mode 100644 files/2013/07/130729153346_737521_50.jpg create mode 100644 files/delete.me create mode 100644 lib/SVG/GPL.txt create mode 100644 lib/SVG/Graph/Bar.rb create mode 100644 lib/SVG/Graph/BarBase.rb create mode 100644 lib/SVG/Graph/BarHorizontal.rb create mode 100644 lib/SVG/Graph/Graph.rb create mode 100644 lib/SVG/Graph/Line.rb create mode 100644 lib/SVG/Graph/Pie.rb create mode 100644 lib/SVG/Graph/Plot.rb create mode 100644 lib/SVG/Graph/Schedule.rb create mode 100644 lib/SVG/Graph/TimeSeries.rb create mode 100644 lib/SVG/LICENSE.txt create mode 100644 lib/diff.rb create mode 100644 lib/generators/redmine_plugin/USAGE create mode 100644 lib/generators/redmine_plugin/redmine_plugin_generator.rb create mode 100644 lib/generators/redmine_plugin/templates/README.rdoc create mode 100644 lib/generators/redmine_plugin/templates/en_rails_i18n.yml create mode 100644 lib/generators/redmine_plugin/templates/init.rb.erb create mode 100644 lib/generators/redmine_plugin/templates/routes.rb create mode 100644 lib/generators/redmine_plugin/templates/test_helper.rb.erb create mode 100644 lib/generators/redmine_plugin_controller/USAGE create mode 100644 lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb create mode 100644 lib/generators/redmine_plugin_controller/templates/controller.rb.erb create mode 100644 lib/generators/redmine_plugin_controller/templates/functional_test.rb.erb create mode 100644 lib/generators/redmine_plugin_controller/templates/helper.rb.erb create mode 100644 lib/generators/redmine_plugin_controller/templates/view.html.erb create mode 100644 lib/generators/redmine_plugin_model/USAGE create mode 100644 lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb create mode 100644 lib/generators/redmine_plugin_model/templates/migration.rb create mode 100644 lib/generators/redmine_plugin_model/templates/model.rb.erb create mode 100644 lib/generators/redmine_plugin_model/templates/unit_test.rb.erb create mode 100644 lib/plugins/acts-as-taggable-on/.rspec create mode 100644 lib/plugins/acts-as-taggable-on/.travis.yml create mode 100644 lib/plugins/acts-as-taggable-on/Appraisals create mode 100644 lib/plugins/acts-as-taggable-on/Gemfile create mode 100644 lib/plugins/acts-as-taggable-on/Guardfile create mode 100644 lib/plugins/acts-as-taggable-on/LICENSE.md create mode 100644 lib/plugins/acts-as-taggable-on/README.md create mode 100644 lib/plugins/acts-as-taggable-on/Rakefile create mode 100644 lib/plugins/acts-as-taggable-on/acts-as-taggable-on.gemspec create mode 100644 lib/plugins/acts-as-taggable-on/gemfiles/rails_3.gemfile create mode 100644 lib/plugins/acts-as-taggable-on/gemfiles/rails_4.gemfile create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts-as-taggable-on.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag_list.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/taggable.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagger.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagging.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tags_helper.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/utils.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/version.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/migration_generator.rb create mode 100644 lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_tagger_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/caching_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/related_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/single_table_inheritance_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_list_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/taggable_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagger_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagging_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tags_helper_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/utils_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/bm.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/database.yml.sample create mode 100644 lib/plugins/acts-as-taggable-on/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/models.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/schema.rb create mode 100644 lib/plugins/acts-as-taggable-on/spec/spec_helper.rb create mode 100644 lib/plugins/acts_as_activity_provider/init.rb create mode 100644 lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb create mode 100644 lib/plugins/acts_as_attachable/init.rb create mode 100644 lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb create mode 100644 lib/plugins/acts_as_customizable/init.rb create mode 100644 lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb create mode 100644 lib/plugins/acts_as_event/init.rb create mode 100644 lib/plugins/acts_as_event/lib/acts_as_event.rb create mode 100644 lib/plugins/acts_as_list/README create mode 100644 lib/plugins/acts_as_list/init.rb create mode 100644 lib/plugins/acts_as_list/lib/active_record/acts/list.rb create mode 100644 lib/plugins/acts_as_list/test/list_test.rb create mode 100644 lib/plugins/acts_as_searchable/init.rb create mode 100644 lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb create mode 100644 lib/plugins/acts_as_tree/README create mode 100644 lib/plugins/acts_as_tree/Rakefile create mode 100644 lib/plugins/acts_as_tree/init.rb create mode 100644 lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb create mode 100644 lib/plugins/acts_as_tree/test/abstract_unit.rb create mode 100644 lib/plugins/acts_as_tree/test/acts_as_tree_test.rb create mode 100644 lib/plugins/acts_as_tree/test/database.yml create mode 100644 lib/plugins/acts_as_tree/test/fixtures/mixin.rb create mode 100644 lib/plugins/acts_as_tree/test/fixtures/mixins.yml create mode 100644 lib/plugins/acts_as_tree/test/schema.rb create mode 100644 lib/plugins/acts_as_versioned/CHANGELOG create mode 100644 lib/plugins/acts_as_versioned/MIT-LICENSE create mode 100644 lib/plugins/acts_as_versioned/README create mode 100644 lib/plugins/acts_as_versioned/RUNNING_UNIT_TESTS create mode 100644 lib/plugins/acts_as_versioned/Rakefile create mode 100644 lib/plugins/acts_as_versioned/init.rb create mode 100644 lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb create mode 100644 lib/plugins/acts_as_versioned/test/abstract_unit.rb create mode 100644 lib/plugins/acts_as_versioned/test/database.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/authors.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/landmark.rb create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/landmarks.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/locked_pages.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/page.rb create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/page_versions.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/pages.yml create mode 100644 lib/plugins/acts_as_versioned/test/fixtures/widget.rb create mode 100644 lib/plugins/acts_as_versioned/test/migration_test.rb create mode 100644 lib/plugins/acts_as_versioned/test/schema.rb create mode 100644 lib/plugins/acts_as_versioned/test/versioned_test.rb create mode 100644 lib/plugins/acts_as_watchable/init.rb create mode 100644 lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb create mode 100644 lib/plugins/awesome_nested_set/.autotest create mode 100644 lib/plugins/awesome_nested_set/.travis.yml create mode 100644 lib/plugins/awesome_nested_set/CHANGELOG create mode 100644 lib/plugins/awesome_nested_set/MIT-LICENSE create mode 100644 lib/plugins/awesome_nested_set/README.rdoc create mode 100644 lib/plugins/awesome_nested_set/Rakefile create mode 100644 lib/plugins/awesome_nested_set/awesome_nested_set.gemspec create mode 100644 lib/plugins/awesome_nested_set/init.rb create mode 100644 lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb create mode 100644 lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb create mode 100644 lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb create mode 100644 lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb create mode 100644 lib/plugins/awesome_nested_set/rails/init.rb create mode 100644 lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb create mode 100644 lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb create mode 100644 lib/plugins/awesome_nested_set/spec/db/database.yml create mode 100644 lib/plugins/awesome_nested_set/spec/db/schema.rb create mode 100644 lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml create mode 100644 lib/plugins/awesome_nested_set/spec/fixtures/categories.yml create mode 100644 lib/plugins/awesome_nested_set/spec/fixtures/departments.yml create mode 100644 lib/plugins/awesome_nested_set/spec/fixtures/notes.yml create mode 100644 lib/plugins/awesome_nested_set/spec/fixtures/things.yml create mode 100644 lib/plugins/awesome_nested_set/spec/spec_helper.rb create mode 100644 lib/plugins/awesome_nested_set/spec/support/models.rb create mode 100644 lib/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb create mode 100644 lib/plugins/awesome_nested_set/test/awesome_nested_set_test.rb create mode 100644 lib/plugins/awesome_nested_set/test/db/database.yml create mode 100644 lib/plugins/awesome_nested_set/test/db/schema.rb create mode 100644 lib/plugins/awesome_nested_set/test/fixtures/categories.yml create mode 100644 lib/plugins/awesome_nested_set/test/fixtures/category.rb create mode 100644 lib/plugins/awesome_nested_set/test/fixtures/departments.yml create mode 100644 lib/plugins/awesome_nested_set/test/fixtures/notes.yml create mode 100644 lib/plugins/awesome_nested_set/test/test_helper.rb create mode 100644 lib/plugins/gravatar/.gitignore create mode 100644 lib/plugins/gravatar/MIT-LICENSE create mode 100644 lib/plugins/gravatar/README.rdoc create mode 100644 lib/plugins/gravatar/Rakefile create mode 100644 lib/plugins/gravatar/about.yml create mode 100644 lib/plugins/gravatar/init.rb create mode 100644 lib/plugins/gravatar/lib/gravatar.rb create mode 100644 lib/plugins/gravatar/spec/gravatar_spec.rb create mode 100644 lib/plugins/open_id_authentication/CHANGELOG create mode 100644 lib/plugins/open_id_authentication/README create mode 100644 lib/plugins/open_id_authentication/Rakefile create mode 100644 lib/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb create mode 100644 lib/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb create mode 100644 lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb create mode 100644 lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb create mode 100644 lib/plugins/open_id_authentication/init.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/association.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/request.rb create mode 100644 lib/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb create mode 100644 lib/plugins/open_id_authentication/lib/tasks/open_id_authentication_tasks.rake create mode 100644 lib/plugins/open_id_authentication/test/mem_cache_store_test.rb create mode 100644 lib/plugins/open_id_authentication/test/normalize_test.rb create mode 100644 lib/plugins/open_id_authentication/test/open_id_authentication_test.rb create mode 100644 lib/plugins/open_id_authentication/test/status_test.rb create mode 100644 lib/plugins/open_id_authentication/test/test_helper.rb create mode 100644 lib/plugins/rfpdf/CHANGELOG create mode 100644 lib/plugins/rfpdf/MIT-LICENSE create mode 100644 lib/plugins/rfpdf/README create mode 100644 lib/plugins/rfpdf/init.rb create mode 100644 lib/plugins/rfpdf/lib/config/lang/eng.rb create mode 100644 lib/plugins/rfpdf/lib/core/image_science.rb create mode 100644 lib/plugins/rfpdf/lib/core/rfpdf.rb create mode 100644 lib/plugins/rfpdf/lib/core/rmagick.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/.noencode create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/DejaVuSans.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSans.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSans.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansBold.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansBold.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansOblique.ctg.z create mode 100644 lib/plugins/rfpdf/lib/fonts/FreeSansOblique.z create mode 100644 lib/plugins/rfpdf/lib/fonts/README.z create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/AUTHORS create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/BUGS create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/LICENSE create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/NEWS create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/README create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/langcover.txt create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/status.txt create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/unicover.txt create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavusans.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavusansb.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/dejavusansi.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/freefont/AUTHORS create mode 100644 lib/plugins/rfpdf/lib/fonts/freefont/CREDITS create mode 100644 lib/plugins/rfpdf/lib/fonts/freefont/ChangeLog create mode 100644 lib/plugins/rfpdf/lib/fonts/freefont/INSTALL create mode 100644 lib/plugins/rfpdf/lib/fonts/freefont/README create mode 100644 lib/plugins/rfpdf/lib/fonts/freesans.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/freesansb.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/freesansbi.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/freesansi.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/helvetica.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/helveticab.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/helveticabi.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/helveticai.rb create mode 100644 lib/plugins/rfpdf/lib/fonts/old/.noencode create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1250.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1251.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1252.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1253.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1254.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1255.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1257.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp1258.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/cp874.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-1.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-11.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-15.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-16.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-2.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-4.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-5.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-7.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-9.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-r.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-u.map create mode 100644 lib/plugins/rfpdf/lib/fonts/old/makefont/makefont.php create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/README.TXT create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/local.conf create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf2ufm/README.TXT create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm create mode 100644 lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm.exe create mode 100644 lib/plugins/rfpdf/lib/fpdf/bookmark.rb create mode 100644 lib/plugins/rfpdf/lib/fpdf/chinese.rb create mode 100644 lib/plugins/rfpdf/lib/fpdf/fpdf_eps.rb create mode 100644 lib/plugins/rfpdf/lib/fpdf/japanese.rb create mode 100644 lib/plugins/rfpdf/lib/fpdf/korean.rb create mode 100644 lib/plugins/rfpdf/lib/fpdf/makefont.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/action_controller.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/action_view.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/errors.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/fpdf.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/math.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/template_handler/compile_support.rb create mode 100644 lib/plugins/rfpdf/lib/rfpdf/template_handlers/base.rb create mode 100644 lib/plugins/rfpdf/lib/tcpdf.rb create mode 100644 lib/plugins/rfpdf/logo_example.png create mode 100644 lib/plugins/rfpdf/test/test_helper.rb create mode 100644 lib/plugins/rfpdf/test_unicode.rfpdf create mode 100644 lib/plugins/rfpdf/utf8test.txt create mode 100644 lib/redcloth3.rb create mode 100644 lib/redmine.rb create mode 100644 lib/redmine/access_control.rb create mode 100644 lib/redmine/access_keys.rb create mode 100644 lib/redmine/activity.rb create mode 100644 lib/redmine/activity/fetcher.rb create mode 100644 lib/redmine/ciphering.rb create mode 100644 lib/redmine/codeset_util.rb create mode 100644 lib/redmine/configuration.rb create mode 100644 lib/redmine/core_ext.rb create mode 100644 lib/redmine/core_ext/active_record.rb create mode 100644 lib/redmine/core_ext/date.rb create mode 100644 lib/redmine/core_ext/date/calculations.rb create mode 100644 lib/redmine/core_ext/string.rb create mode 100644 lib/redmine/core_ext/string/conversions.rb create mode 100644 lib/redmine/core_ext/string/inflections.rb create mode 100644 lib/redmine/custom_field_format.rb create mode 100644 lib/redmine/default_data/loader.rb create mode 100644 lib/redmine/export/pdf.rb create mode 100644 lib/redmine/helpers/calendar.rb create mode 100644 lib/redmine/helpers/diff.rb create mode 100644 lib/redmine/helpers/gantt.rb create mode 100644 lib/redmine/helpers/time_report.rb create mode 100644 lib/redmine/hook.rb create mode 100644 lib/redmine/i18n.rb create mode 100644 lib/redmine/imap.rb create mode 100644 lib/redmine/info.rb create mode 100644 lib/redmine/menu_manager.rb create mode 100644 lib/redmine/mime_type.rb create mode 100644 lib/redmine/notifiable.rb create mode 100644 lib/redmine/pagination.rb create mode 100644 lib/redmine/platform.rb create mode 100644 lib/redmine/plugin.rb create mode 100644 lib/redmine/pop3.rb create mode 100644 lib/redmine/safe_attributes.rb create mode 100644 lib/redmine/scm/adapters/abstract_adapter.rb create mode 100644 lib/redmine/scm/adapters/bazaar_adapter.rb create mode 100644 lib/redmine/scm/adapters/cvs_adapter.rb create mode 100644 lib/redmine/scm/adapters/darcs_adapter.rb create mode 100644 lib/redmine/scm/adapters/filesystem_adapter.rb create mode 100644 lib/redmine/scm/adapters/git_adapter.rb create mode 100644 lib/redmine/scm/adapters/mercurial/hg-template-1.0.tmpl create mode 100644 lib/redmine/scm/adapters/mercurial/redminehelper.py create mode 100644 lib/redmine/scm/adapters/mercurial_adapter.rb create mode 100644 lib/redmine/scm/adapters/subversion_adapter.rb create mode 100644 lib/redmine/scm/base.rb create mode 100644 lib/redmine/search.rb create mode 100644 lib/redmine/subclass_factory.rb create mode 100644 lib/redmine/syntax_highlighting.rb create mode 100644 lib/redmine/themes.rb create mode 100644 lib/redmine/thumbnail.rb create mode 100644 lib/redmine/unified_diff.rb create mode 100644 lib/redmine/utils.rb create mode 100644 lib/redmine/version.rb create mode 100644 lib/redmine/views/api_template_handler.rb create mode 100644 lib/redmine/views/builders.rb create mode 100644 lib/redmine/views/builders/json.rb create mode 100644 lib/redmine/views/builders/structure.rb create mode 100644 lib/redmine/views/builders/xml.rb create mode 100644 lib/redmine/views/labelled_form_builder.rb create mode 100644 lib/redmine/views/my_page/block.rb create mode 100644 lib/redmine/views/other_formats_builder.rb create mode 100644 lib/redmine/wiki_formatting.rb create mode 100644 lib/redmine/wiki_formatting/macros.rb create mode 100644 lib/redmine/wiki_formatting/textile/formatter.rb create mode 100644 lib/redmine/wiki_formatting/textile/helper.rb create mode 100644 lib/tasks/ci.rake create mode 100644 lib/tasks/ciphering.rake create mode 100644 lib/tasks/deprecated.rake create mode 100644 lib/tasks/email.rake create mode 100644 lib/tasks/extract_fixtures.rake create mode 100644 lib/tasks/initializers.rake create mode 100644 lib/tasks/jdbc.rake create mode 100644 lib/tasks/load_default_data.rake create mode 100644 lib/tasks/locales.rake create mode 100644 lib/tasks/metrics.rake create mode 100644 lib/tasks/migrate_from_mantis.rake create mode 100644 lib/tasks/migrate_from_trac.rake create mode 100644 lib/tasks/permissions.rake create mode 100644 lib/tasks/redmine.rake create mode 100644 lib/tasks/reminder.rake create mode 100644 lib/tasks/testing.rake create mode 100644 lib/tasks/yardoc.rake create mode 100644 plugins/README create mode 100644 public/404.html create mode 100644 public/500.html create mode 100644 public/application.css create mode 100644 public/dispatch.fcgi.example create mode 100644 public/favicon.ico create mode 100644 public/favicon.old.ico create mode 100644 public/help/wiki_syntax.html create mode 100644 public/help/wiki_syntax_detailed.html create mode 100644 public/htaccess.fcgi.example create mode 100644 public/images/115960_50.jpg create mode 100644 public/images/121944_50.jpg create mode 100644 public/images/12_50.png create mode 100644 public/images/1downarrow.png create mode 100644 public/images/1uparrow.png create mode 100644 public/images/233683_50.jpg create mode 100644 public/images/28_50.jpg create mode 100644 public/images/2downarrow.png create mode 100644 public/images/2uparrow.png create mode 100644 public/images/47318_50.jpg create mode 100644 public/images/737521_50.jpg create mode 100644 public/images/860270_50.jpg create mode 100644 public/images/926055_50.jpg create mode 100644 public/images/add.png create mode 100644 public/images/arrow_collapsed.png create mode 100644 public/images/arrow_down.png create mode 100644 public/images/arrow_expanded.png create mode 100644 public/images/attachment.png create mode 100644 public/images/avatars/AnonymousUser/0 create mode 100644 public/images/avatars/Project/0 create mode 100644 public/images/avatars/Project/6314 create mode 100644 public/images/avatars/User/0 create mode 100644 public/images/avatars/User/1 create mode 100644 public/images/avatars/User/4245 create mode 100644 public/images/avatars/User/4246 create mode 100644 public/images/avatars/User/4247 create mode 100644 public/images/avatars/User/4249 create mode 100644 public/images/avatars/User/4275 create mode 100644 public/images/avatars/User/4288 create mode 100644 public/images/avatars/User/4856 create mode 100644 public/images/avatars/User/4858 create mode 100644 public/images/avatars/User/4859 create mode 100644 public/images/avatars/User/4861 create mode 100644 public/images/avatars/User/4863 create mode 100644 public/images/bullet_add.png create mode 100644 public/images/bullet_arrow_left.png create mode 100644 public/images/bullet_arrow_right.png create mode 100644 public/images/bullet_black.png create mode 100644 public/images/bullet_blue.png create mode 100644 public/images/bullet_delete.png create mode 100644 public/images/bullet_diamond.png create mode 100644 public/images/bullet_end.png create mode 100644 public/images/bullet_go.png create mode 100644 public/images/bullet_orange.png create mode 100644 public/images/bullet_purple.png create mode 100644 public/images/bullet_toggle_minus.png create mode 100644 public/images/bullet_toggle_plus.png create mode 100644 public/images/calendar.png create mode 100644 public/images/cancel.png create mode 100644 public/images/changeset.png create mode 100644 public/images/close.png create mode 100644 public/images/close_hl.png create mode 100644 public/images/comment.png create mode 100644 public/images/comments.png create mode 100644 public/images/copy.png create mode 100644 public/images/database_key.png create mode 100644 public/images/delete.png create mode 100644 public/images/document.png create mode 100644 public/images/draft.png create mode 100644 public/images/duplicate.png create mode 100644 public/images/edit.png create mode 100644 public/images/exclamation.png create mode 100644 public/images/external.png create mode 100644 public/images/false.png create mode 100644 public/images/fav.png create mode 100644 public/images/fav_off.png create mode 100644 public/images/feed.png create mode 100644 public/images/files/c.png create mode 100644 public/images/files/csharp.png create mode 100644 public/images/files/css.png create mode 100644 public/images/files/default.png create mode 100644 public/images/files/html.png create mode 100644 public/images/files/image.png create mode 100644 public/images/files/java.png create mode 100644 public/images/files/js.png create mode 100644 public/images/files/pdf.png create mode 100644 public/images/files/php.png create mode 100644 public/images/files/ruby.png create mode 100644 public/images/files/text.png create mode 100644 public/images/files/xml.png create mode 100644 public/images/files/zip.png create mode 100644 public/images/folder.png create mode 100644 public/images/folder_open.png create mode 100644 public/images/folder_open_add.png create mode 100644 public/images/folder_open_orange.png create mode 100644 public/images/group.png create mode 100644 public/images/help.png create mode 100644 public/images/history.png create mode 100644 public/images/home_images/2.png create mode 100644 public/images/home_images/3.png create mode 100644 public/images/home_images/BackGround.gif create mode 100644 public/images/home_images/logo1.png create mode 100644 public/images/home_new.png create mode 100644 public/images/home_project.png create mode 100644 public/images/home_req.png create mode 100644 public/images/hourglass.png create mode 100644 public/images/jstoolbar/bt_bq.png create mode 100644 public/images/jstoolbar/bt_bq_remove.png create mode 100644 public/images/jstoolbar/bt_code.png create mode 100644 public/images/jstoolbar/bt_del.png create mode 100644 public/images/jstoolbar/bt_em.png create mode 100644 public/images/jstoolbar/bt_h1.png create mode 100644 public/images/jstoolbar/bt_h2.png create mode 100644 public/images/jstoolbar/bt_h3.png create mode 100644 public/images/jstoolbar/bt_img.png create mode 100644 public/images/jstoolbar/bt_ins.png create mode 100644 public/images/jstoolbar/bt_link.png create mode 100644 public/images/jstoolbar/bt_ol.png create mode 100644 public/images/jstoolbar/bt_pre.png create mode 100644 public/images/jstoolbar/bt_strong.png create mode 100644 public/images/jstoolbar/bt_ul.png create mode 100644 public/images/jstoolbar/logo1.png create mode 100644 public/images/lightning.png create mode 100644 public/images/link.png create mode 100644 public/images/link_break.png create mode 100644 public/images/loading.gif create mode 100644 public/images/locked.png create mode 100644 public/images/logo-only_med.png create mode 100644 public/images/magnifier.png create mode 100644 public/images/message.png create mode 100644 public/images/milestone_done.png create mode 100644 public/images/milestone_late.png create mode 100644 public/images/milestone_todo.png create mode 100644 public/images/move.png create mode 100644 public/images/new/fenxiang.png create mode 100644 public/images/new/liuyan.png create mode 100644 public/images/new/liuyan2.png create mode 100644 public/images/new/logo.gif create mode 100644 public/images/new/logo.png create mode 100644 public/images/new/logo_top.png create mode 100644 public/images/new/mlogo.png create mode 100644 public/images/new/news.png create mode 100644 public/images/new/small.png create mode 100644 public/images/new/user.jpg create mode 100644 public/images/new/zhishu.png create mode 100644 public/images/new/zhishu2.png create mode 100644 public/images/news.png create mode 100644 public/images/openid-bg.gif create mode 100644 public/images/package.png create mode 100644 public/images/pai.png create mode 100644 public/images/plugin.png create mode 100644 public/images/project_marker.png create mode 100644 public/images/projects.png create mode 100644 public/images/reload.png create mode 100644 public/images/report.png create mode 100644 public/images/requirements/req.jpg create mode 100644 public/images/save.png create mode 100644 public/images/server_key.png create mode 100644 public/images/sidebar/fork.png create mode 100644 public/images/sidebar/tag_title.png create mode 100644 public/images/sidebar/tool_tag.png create mode 100644 public/images/sidebar/watch.png create mode 100644 public/images/sort_asc.png create mode 100644 public/images/sort_desc.png create mode 100644 public/images/stars_ro.png create mode 100644 public/images/stats.png create mode 100644 public/images/table_multiple.png create mode 100644 public/images/task_done.png create mode 100644 public/images/task_late.png create mode 100644 public/images/task_parent_end.png create mode 100644 public/images/task_todo.png create mode 100644 public/images/text_list_bullets.png create mode 100644 public/images/textfield.png create mode 100644 public/images/textfield_key.png create mode 100644 public/images/ticket.png create mode 100644 public/images/ticket_checked.png create mode 100644 public/images/ticket_edit.png create mode 100644 public/images/ticket_go.png create mode 100644 public/images/ticket_note.png create mode 100644 public/images/time.png create mode 100644 public/images/time_add.png create mode 100644 public/images/toggle_check.png create mode 100644 public/images/true.png create mode 100644 public/images/unlock.png create mode 100644 public/images/user.png create mode 100644 public/images/user_images/L1.png create mode 100644 public/images/user_images/L2.png create mode 100644 public/images/user_images/L3.png create mode 100644 public/images/user_images/fans.png create mode 100644 public/images/user_images/fork.png create mode 100644 public/images/user_images/in_share.png create mode 100644 public/images/user_images/iuser.png create mode 100644 public/images/user_images/m1.png create mode 100644 public/images/user_images/m2.png create mode 100644 public/images/user_images/me.jpg create mode 100644 public/images/user_images/mlogo.png create mode 100644 public/images/user_images/project.jpg create mode 100644 public/images/user_images/project.png create mode 100644 public/images/user_images/share.png create mode 100644 public/images/user_images/user2.png create mode 100644 public/images/user_images/watch.png create mode 100644 public/images/user_images/watchers.png create mode 100644 public/images/version_marker.png create mode 100644 public/images/warning.png create mode 100644 public/images/watcher/watcher_button.png create mode 100644 public/images/welcome/1.png create mode 100644 public/images/welcome/2.png create mode 100644 public/images/welcome/3.png create mode 100644 public/images/welcome/4.png create mode 100644 public/images/welcome/background.png create mode 100644 public/images/welcome/background2.png create mode 100644 public/images/welcome/background3.png create mode 100644 public/images/welcome/backgroundnew.png create mode 100644 public/images/wiki_edit.png create mode 100644 public/images/zoom_in.png create mode 100644 public/images/zoom_out.png create mode 100644 public/javascripts/application.js create mode 100644 public/javascripts/attachments.js create mode 100644 public/javascripts/avatars.js create mode 100644 public/javascripts/context_menu.js create mode 100644 public/javascripts/gantt.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ar.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-az.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-bg.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-bs.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ca.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-cs.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-da.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-de.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-el.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-en-GB.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-es.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-et.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-eu.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-fa.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-fi.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-fr.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-gl.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-he.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-hr.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-hu.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-id.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-it.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ja.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ko.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-lt.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-lv.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-mk.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-nl.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-no.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-pl.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-pt-BR.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-pt.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ro.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-ru.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-sk.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-sl.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-sq.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-sr.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-sv.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-th.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-tr.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-uk.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-vi.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-zh-CN.js create mode 100644 public/javascripts/i18n/jquery.ui.datepicker-zh-TW.js create mode 100644 public/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js create mode 100644 public/javascripts/jstoolbar/jstoolbar-textile.min.js create mode 100644 public/javascripts/jstoolbar/jstoolbar.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ar.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-az.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-bg.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-bs.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ca.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-cs.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-da.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-de.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-en-gb.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-en.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-es.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-et.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-eu.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-fa.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-fi.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-fr.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-gl.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-he.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-hr.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-hu.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-id.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-it.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ja.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ko.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-lt.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-lv.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-mk.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-mn.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-nl.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-no.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-pl.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-pt-br.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-pt.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ro.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-ru.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sk.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sl.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sq.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sr-yu.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sr.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-sv.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-th.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-tr.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-uk.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-vi.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-zh-tw.js create mode 100644 public/javascripts/jstoolbar/lang/jstoolbar-zh.js create mode 100644 public/javascripts/jstoolbar/textile.js create mode 100644 public/javascripts/project_identifier.js create mode 100644 public/javascripts/raphael.js create mode 100644 public/javascripts/repository_navigation.js create mode 100644 public/javascripts/revision_graph.js create mode 100644 public/javascripts/select_list_move.js create mode 100644 public/stylesheets/application.css create mode 100644 public/stylesheets/context_menu.css create mode 100644 public/stylesheets/context_menu_rtl.css create mode 100644 public/stylesheets/jquery/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 public/stylesheets/jquery/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 public/stylesheets/jquery/images/ui-bg_flat_10_000000_40x100.png create mode 100644 public/stylesheets/jquery/images/ui-bg_glass_100_eef5fd_1x400.png create mode 100644 public/stylesheets/jquery/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 public/stylesheets/jquery/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 public/stylesheets/jquery/images/ui-bg_gloss-wave_35_759fcf_500x100.png create mode 100644 public/stylesheets/jquery/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 public/stylesheets/jquery/images/ui-bg_highlight-soft_75_759fcf_1x100.png create mode 100644 public/stylesheets/jquery/images/ui-icons_222222_256x240.png create mode 100644 public/stylesheets/jquery/images/ui-icons_759fcf_256x240.png create mode 100644 public/stylesheets/jquery/images/ui-icons_ffd27a_256x240.png create mode 100644 public/stylesheets/jquery/images/ui-icons_ffffff_256x240.png create mode 100644 public/stylesheets/jquery/jquery-ui-1.9.2.css create mode 100644 public/stylesheets/jstoolbar.css create mode 100644 public/stylesheets/rtl.css create mode 100644 public/stylesheets/scm.css create mode 100644 public/stylesheetsold/application.css create mode 100644 public/stylesheetsold/context_menu.css create mode 100644 public/stylesheetsold/context_menu_rtl.css create mode 100644 public/stylesheetsold/jquery/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_flat_10_000000_40x100.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_glass_100_eef5fd_1x400.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_gloss-wave_35_759fcf_500x100.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 public/stylesheetsold/jquery/images/ui-bg_highlight-soft_75_759fcf_1x100.png create mode 100644 public/stylesheetsold/jquery/images/ui-icons_222222_256x240.png create mode 100644 public/stylesheetsold/jquery/images/ui-icons_759fcf_256x240.png create mode 100644 public/stylesheetsold/jquery/images/ui-icons_ffd27a_256x240.png create mode 100644 public/stylesheetsold/jquery/images/ui-icons_ffffff_256x240.png create mode 100644 public/stylesheetsold/jquery/jquery-ui-1.9.2.css create mode 100644 public/stylesheetsold/jstoolbar.css create mode 100644 public/stylesheetsold/rtl.css create mode 100644 public/stylesheetsold/scm.css create mode 100644 public/themes/README create mode 100644 public/themes/alternate/stylesheets/application.css create mode 100644 public/themes/classic/images/home.png create mode 100644 public/themes/classic/images/wrench.png create mode 100644 public/themes/classic/stylesheets/application.css create mode 100644 public/themes/redpenny-master/README.md create mode 100644 public/themes/redpenny-master/images/bg/bg.gif create mode 100644 public/themes/redpenny-master/images/bg/bg.jpg create mode 100644 public/themes/redpenny-master/images/bg/f.jpg create mode 100644 public/themes/redpenny-master/images/bullet.png create mode 100644 public/themes/redpenny-master/images/logo.png create mode 100644 public/themes/redpenny-master/stylesheets/application.css create mode 100644 public/themes/redpenny-master/stylesheets/font/FontAwesome.otf create mode 100644 public/themes/redpenny-master/stylesheets/font/fontawesome-webfont.eot create mode 100644 public/themes/redpenny-master/stylesheets/font/fontawesome-webfont.svg create mode 100644 public/themes/redpenny-master/stylesheets/font/fontawesome-webfont.ttf create mode 100644 public/themes/redpenny-master/stylesheets/font/fontawesome-webfont.woff create mode 100644 public/themes/redpenny-master/stylesheets/images/bg.png create mode 100644 public/themes/redpenny-master/stylesheets/images/bg/bg.gif create mode 100644 public/themes/redpenny-master/stylesheets/images/bg/bg.jpg create mode 100644 public/themes/redpenny-master/stylesheets/images/bg/f.jpg create mode 100644 public/themes/redpenny-master/stylesheets/images/bullet.png create mode 100644 public/themes/redpenny-master/stylesheets/images/log.png create mode 100644 public/themes/redpenny-master/stylesheets/images/logo.png create mode 100644 public/themes/redpenny-master/stylesheets/images/logo/bg.png create mode 100644 script/about create mode 100644 script/rails diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..8e575ed77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +log/* +.bundle +test/* +tmp/bids/server.pid +tmp/* +/tmp/cache/* +/tmp/pdf/* +/tmp/sessions/* +/tmp/sockets/* +/tmp/test/* +/tmp/thumbnails/* +.project +.svn/ +.git/ +.bundle +log +/log/development.log +/log/development.scm.stderr.log +/log/delete.me +/test/* diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..9fde48651 --- /dev/null +++ b/.hgignore @@ -0,0 +1,39 @@ +syntax: glob + +.project +.loadpath +config/additional_environment.rb +config/configuration.yml +config/database.yml +config/email.yml +config/initializers/session_store.rb +config/initializers/secret_token.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/pdf/* +tmp/sessions/* +tmp/sockets/* +tmp/test/* +tmp/thumbnails/* +vendor/cache +vendor/rails +*.rbc + +.svn/ +.git/ + +.bundle +Gemfile.lock +Gemfile.local + diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..261b71b7d --- /dev/null +++ b/Gemfile @@ -0,0 +1,95 @@ +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 "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] +gem "builder", "3.0.0" +gem 'acts-as-taggable-on' +# 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.12.3" + gem 'capybara', '~> 2.0.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 --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..99f29e915 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,155 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (3.2.13) + actionpack (= 3.2.13) + mail (~> 2.5.3) + actionpack (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.4) + rack (~> 1.4.5) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.2.1) + activemodel (3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activeresource (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + acts-as-taggable-on (2.4.1) + rails (>= 3, < 5) + arel (3.0.2) + builder (3.0.0) + capybara (2.0.3) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 1.0.0) + childprocess (0.3.9) + ffi (~> 1.0, >= 1.0.11) + coderay (1.0.9) + erubis (2.7.0) + fastercsv (1.5.5) + ffi (1.9.0-x86-mingw32) + hike (1.2.3) + i18n (0.6.1) + journey (1.0.4) + jquery-rails (2.0.3) + railties (>= 3.1.0, < 5.0) + thor (~> 0.14) + json (1.8.0) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) + metaclass (0.0.1) + mime-types (1.23) + mini_portile (0.5.0) + mocha (0.12.10) + metaclass (~> 0.0.1) + multi_json (1.7.6) + mysql2 (0.3.11-x86-mingw32) + net-ldap (0.3.1) + nokogiri (1.6.0-x86-mingw32) + mini_portile (~> 0.5.0) + pg (0.14.1-x86-mingw32) + polyglot (0.3.3) + rack (1.4.5) + rack-cache (1.2) + rack (>= 0.4) + rack-openid (1.3.1) + rack (>= 1.1.0) + ruby-openid (>= 2.1.8) + rack-ssl (1.3.3) + rack + rack-test (0.6.2) + rack (>= 1.0) + rails (3.2.13) + actionmailer (= 3.2.13) + actionpack (= 3.2.13) + activerecord (= 3.2.13) + activeresource (= 3.2.13) + activesupport (= 3.2.13) + bundler (~> 1.0) + railties (= 3.2.13) + railties (3.2.13) + actionpack (= 3.2.13) + activesupport (= 3.2.13) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (>= 0.14.6, < 2.0) + rake (10.0.4) + rdoc (3.12.2) + json (~> 1.4) + rmagick (2.13.2) + ruby-openid (2.1.8) + rubyzip (0.9.9) + selenium-webdriver (2.33.0) + childprocess (>= 0.2.5) + multi_json (~> 1.0) + rubyzip + websocket (~> 1.0.4) + shoulda (3.3.2) + shoulda-context (~> 1.0.1) + shoulda-matchers (~> 1.4.1) + shoulda-context (1.0.2) + shoulda-matchers (1.4.1) + activesupport (>= 3.0.0) + sprockets (2.2.2) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + sqlite3 (1.3.7-x86-mingw32) + thor (0.18.1) + tilt (1.4.1) + treetop (1.4.14) + polyglot + polyglot (>= 0.3.1) + tzinfo (0.3.37) + websocket (1.0.7) + xpath (1.0.0) + nokogiri (~> 1.3) + yard (0.8.6.1) + +PLATFORMS + x86-mingw32 + +DEPENDENCIES + activerecord-jdbc-adapter (= 1.2.5) + activerecord-jdbcmysql-adapter + activerecord-jdbcpostgresql-adapter + activerecord-jdbcsqlite3-adapter + acts-as-taggable-on + builder (= 3.0.0) + capybara (~> 2.0.0) + coderay (~> 1.0.6) + fastercsv (~> 1.5.0) + i18n (~> 0.6.0) + jquery-rails (~> 2.0.2) + mocha (~> 0.12.3) + mysql2 (~> 0.3.11) + net-ldap (~> 0.3.1) + pg (>= 0.11.0) + rack-openid + rails (= 3.2.13) + rdoc (>= 2.4.2) + rmagick (>= 2.0.0) + ruby-openid (~> 2.1.4) + shoulda (~> 3.3.2) + sqlite3 + yard diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 000000000..4132fb86e --- /dev/null +++ b/README.rdoc @@ -0,0 +1,5 @@ += Redmine + +Redmine is a flexible project management web application written using Ruby on Rails framework. + +More details can be found in the doc directory or on the official website http://www.redmine.org diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..5fbdf84ca --- /dev/null +++ b/Rakefile @@ -0,0 +1,7 @@ +#!/usr/bin/env rake +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +RedmineApp::Application.load_tasks diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb new file mode 100644 index 000000000..ad7443ab5 --- /dev/null +++ b/app/controllers/account_controller.rb @@ -0,0 +1,307 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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 }) + #by young +# redirect_back_or_default my_page_path + redirect_back_or_default User.current +# redirect_to User.current + 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 --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb new file mode 100644 index 000000000..83b97f7d3 --- /dev/null +++ b/app/controllers/activities_controller.rb @@ -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. + +class ActivitiesController < ApplicationController + menu_item :activity + before_filter :find_optional_project, :index + accept_rss_auth :index + helper :Watchers + + def index + @days = Setting.activity_days_default.to_i + + if params[:from] + begin; @date_to = params[:from].to_date + 1; rescue; end + end + + has = { + "show_issues" => true + } + @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| !has["show_#{t}"].nil?} + #@activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? + + events = @activity.events(@date_from, @date_to) + # Added by Nie. + @offset, @limit = api_offset_and_limit({:limit => 10}) + @activity_count = events.size + @activity_pages = Paginator.new @activity_count, @limit, params['page'] + @offset ||= @activity_pages.offset + + @project_base_tag = params[:id]?'base_projects':'base' + 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.slice(@offset,@limit) + @events_by_day = @events_by_day_.group_by {|event| User.current.time_to_date(event.event_datetime)} + #by young render :layout => false if request.xhr? + render :layout => @project_base_tag + } + 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 --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb new file mode 100644 index 000000000..f96cf66fb --- /dev/null +++ b/app/controllers/admin_controller.rb @@ -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 --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..e68085109 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,610 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# 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 + #by young + if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)}) && (uri.path!='/') + 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 + offset ||= 0 + end + + + [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 --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb new file mode 100644 index 000000000..5a816a735 --- /dev/null +++ b/app/controllers/attachments_controller.rb @@ -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 --git a/app/controllers/auth_sources_controller.rb b/app/controllers/auth_sources_controller.rb new file mode 100644 index 000000000..1ac5ca391 --- /dev/null +++ b/app/controllers/auth_sources_controller.rb @@ -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 --git a/app/controllers/auto_completes_controller.rb b/app/controllers/auto_completes_controller.rb new file mode 100644 index 000000000..ea463e121 --- /dev/null +++ b/app/controllers/auto_completes_controller.rb @@ -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 --git a/app/controllers/avatar_controller.rb b/app/controllers/avatar_controller.rb new file mode 100644 index 000000000..0cf2014e4 --- /dev/null +++ b/app/controllers/avatar_controller.rb @@ -0,0 +1,78 @@ +class AvatarController < ApplicationController + + + #before_filter :set_cache_buster + include AvatarHelper + + 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 + + unless request.raw_post.nil? + @source_type = params[:source_type] + @source_id = params[:source_id] + @temp_file = request.raw_post + if @temp_file.size > 0 + if @temp_file.respond_to?(:original_filename) + @image_file = @temp_file.original_filename + #image_file.force_encoding("UTF-8") if filename.respond_to?(:force_encoding) + else + @image_file=params[:filename] + end + end + end + if @temp_file && (@temp_file.size > 0) + diskfile=disk_filename(@source_type,@source_id) + @urlfile='/' << File.join("images","avatars",avatar_directory(@source_type),avatar_filename(@source_id,@image_file)) + logger.info("Saving avatar '#{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 + # @avatar = Avatar.new(:receive_file => request.raw_post) + # @avatar.source_id = User.current.id + # @avatar.image_file = params[:filename].presence || Redmine::Utils.random_hex(16) + # saved = @avatar.save + + respond_to do |format| + format.js + format.api { + if saved + render :action => 'upload', :status => :created + else + render_validation_errors(@avatar) + end + } + end + end + + private + + def set_cache_buster + response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" + response.headers["Pragma"] = "no-cache" + response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" + end + + +end diff --git a/app/controllers/bids_controller.rb b/app/controllers/bids_controller.rb new file mode 100644 index 000000000..e785ff381 --- /dev/null +++ b/app/controllers/bids_controller.rb @@ -0,0 +1,154 @@ +class BidsController < ApplicationController + + before_filter :find_bid, :only => [:show, :show_project, :create, :destroy, :more, :back, :add] + + helper :watchers + def index + if params[:bid_title] + Bid.creat_bids(params[:bid_budget], params[:bid_deadline], params[:bid_title] , params[:bid_description]) + end + # @requirement_title = "4" + @offset = 0 + @limit = 20 + @bids = Bid.offset(@offset).limit(@limit).all + + end + + def show + @state = false + @user = @bid.author + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + # + # @journals = @bid.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all + #@journals.each_with_index {|j,i| j.indice = i+1} + respond_to do |format| + format.html { + render :layout => 'base_bids' + } + format.api + + end + end + + def show_project + @user = @bid.author + @bidding_project = @bid.biding_projects + respond_to do |format| + format.html { + render :layout => 'base_bids' + } + format.api + end + end + + def add + project_id = params[:bid_for_save][:project_id] + bid_message = params[:bid_for_save][:bid_message] + BidingProject.cerate_bidding(@bid.id, project_id, bid_message) + @bidding_project = @bid.biding_projects + 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 create + if params[:user_message].size>0 + message = params[:user_message] + @bid.add_jour(User.current, message) + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + end + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @bid.set_commit(@jour.count) + + 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 destroy + JournalsForMessage.delete_message(params[:object_id]) + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @bid.set_commit(@jour.count) + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def new + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @bid.author + text = @bid.description + end + # Replaces pre blocks with [...] + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}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 new_bid + + end + + def more + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def back + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + private + + def find_bid + if params[:bid_id] + @bid = Bid.find(params[:bid_id]) + end + rescue + render_404 + end + +end + diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb new file mode 100644 index 000000000..47f5c0f07 --- /dev/null +++ b/app/controllers/boards_controller.rb @@ -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 --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb new file mode 100644 index 000000000..c8f8bbbd7 --- /dev/null +++ b/app/controllers/calendars_controller.rb @@ -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 => 'base_projects' + end +end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 000000000..b2689d0c2 --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -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 --git a/app/controllers/context_menus_controller.rb b/app/controllers/context_menus_controller.rb new file mode 100644 index 000000000..bc434ea12 --- /dev/null +++ b/app/controllers/context_menus_controller.rb @@ -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 --git a/app/controllers/custom_fields_controller.rb b/app/controllers/custom_fields_controller.rb new file mode 100644 index 000000000..c20516a1d --- /dev/null +++ b/app/controllers/custom_fields_controller.rb @@ -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 --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb new file mode 100644 index 000000000..8daba49c6 --- /dev/null +++ b/app/controllers/documents_controller.rb @@ -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 DocumentsController < ApplicationController + layout 'base_projects' + 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 --git a/app/controllers/enumerations_controller.rb b/app/controllers/enumerations_controller.rb new file mode 100644 index 000000000..4e5475bec --- /dev/null +++ b/app/controllers/enumerations_controller.rb @@ -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.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 --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb new file mode 100644 index 000000000..468ad72e5 --- /dev/null +++ b/app/controllers/files_controller.rb @@ -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. + +class FilesController < ApplicationController + layout 'base_projects' + 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 --git a/app/controllers/gantts_controller.rb b/app/controllers/gantts_controller.rb new file mode 100644 index 000000000..a7d4039db --- /dev/null +++ b/app/controllers/gantts_controller.rb @@ -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 => 'base_projects' } + 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 --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb new file mode 100644 index 000000000..b2f9d6af5 --- /dev/null +++ b/app/controllers/groups_controller.rb @@ -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 --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb new file mode 100644 index 000000000..371d9379b --- /dev/null +++ b/app/controllers/issue_categories_controller.rb @@ -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{render :layout => 'base_projects'} + 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 --git a/app/controllers/issue_relations_controller.rb b/app/controllers/issue_relations_controller.rb new file mode 100644 index 000000000..cd008529a --- /dev/null +++ b/app/controllers/issue_relations_controller.rb @@ -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 --git a/app/controllers/issue_statuses_controller.rb b/app/controllers/issue_statuses_controller.rb new file mode 100644 index 000000000..cedd6a9f9 --- /dev/null +++ b/app/controllers/issue_statuses_controller.rb @@ -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 --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb new file mode 100644 index 000000000..4d0ea7595 --- /dev/null +++ b/app/controllers/issues_controller.rb @@ -0,0 +1,443 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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 + + @project_base_tag = (params[:project_id] || @issue.project)?'base_projects':'base'#by young + + 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 => @project_base_tag }#by young + 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 => @project_base_tag) }#by young + 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) + + @project_base_tag = (params[:project_id] || @issue.project)?'base_projects':'base'#by young + respond_to do |format| + format.html { + retrieve_previous_and_next_issue_ids + render :template => 'issues/show', :layout => @project_base_tag#by young + } + 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 => 'base_projects' } + 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 --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb new file mode 100644 index 000000000..ad6728e37 --- /dev/null +++ b/app/controllers/journals_controller.rb @@ -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{
((.|\s)*?)
}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 --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb new file mode 100644 index 000000000..f99982d46 --- /dev/null +++ b/app/controllers/list_controller.rb @@ -0,0 +1,5 @@ +class ListController < ApplicationController + def members + + end +end \ No newline at end of file diff --git a/app/controllers/mail_handler_controller.rb b/app/controllers/mail_handler_controller.rb new file mode 100644 index 000000000..3a4b219bb --- /dev/null +++ b/app/controllers/mail_handler_controller.rb @@ -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 --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb new file mode 100644 index 000000000..c46b62879 --- /dev/null +++ b/app/controllers/members_controller.rb @@ -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 --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb new file mode 100644 index 000000000..ad9107639 --- /dev/null +++ b/app/controllers/messages_controller.rb @@ -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{
((.|\s)*?)
}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 --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb new file mode 100644 index 000000000..84f5b20ca --- /dev/null +++ b/app/controllers/my_controller.rb @@ -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 --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb new file mode 100644 index 000000000..1002438bb --- /dev/null +++ b/app/controllers/news_controller.rb @@ -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 NewsController < ApplicationController + layout 'base_projects' + 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 --git a/app/controllers/previews_controller.rb b/app/controllers/previews_controller.rb new file mode 100644 index 000000000..d19a7fcd7 --- /dev/null +++ b/app/controllers/previews_controller.rb @@ -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 --git a/app/controllers/project_enumerations_controller.rb b/app/controllers/project_enumerations_controller.rb new file mode 100644 index 000000000..c473102af --- /dev/null +++ b/app/controllers/project_enumerations_controller.rb @@ -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 --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb new file mode 100644 index 000000000..ccd90474e --- /dev/null +++ b/app/controllers/projects_controller.rb @@ -0,0 +1,365 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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 + layout 'base_projects' + 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, :member, :focus, :investor, :issue, :mission, :on, :file] + before_filter :authorize_global, :only => [:new, :create] + before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] + #by young + before_filter :member, :focus, :mission, :issue, :on, :file, :investor + # + 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 + helper :activities + helper :documents + helper :watchers + + + # 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 index + @offset, @limit = api_offset_and_limit({:limit => 10}) + @project_count = Project.visible.count + @project_pages = Paginator.new @project_count, @limit, params['page'] + @offset ||= @project_pages.offset + @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all + respond_to do |format| + format.html { + render :layout => 'base' + scope = Project + unless params[:closed] + scope = scope.active + end + @projects = scope.visible.offset(@offset).limit(@limit).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 + #新增内容 + @days = Setting.activity_days_default.to_i + + if params[:from] + begin; @date_to = params[:from].to_date + 1; rescue; end + end + + has = { + "show_issues" => true + } + @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| !has["show_#{t}"].nil?} + # @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? + + events = @activity.events(@date_from, @date_to, {:limit=>15}) + @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} + # documents + @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 +# + 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 + + #by young + def member + session[:project_member_num] = 12 + end + + def focus + session[:project_focus_num] = 2508 + end + + def investor + session[:project_investor_num] = 8 + end + + def issue + session[:project_issue_num] = 1 + end + + def mission + session[:project_mission_num] = 225 + end + + def on + session[:project_on_num] = 1208 + end + + def file + session[:project_file_num] = 125 + end + #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 --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb new file mode 100644 index 000000000..639255125 --- /dev/null +++ b/app/controllers/queries_controller.rb @@ -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 --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb new file mode 100644 index 000000000..dbdf44545 --- /dev/null +++ b/app/controllers/reports_controller.rb @@ -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 --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb new file mode 100644 index 000000000..03b5967fe --- /dev/null +++ b/app/controllers/repositories_controller.rb @@ -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. + +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 + layout 'base_projects' + 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 => 650, + :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 => 650, + :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 --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb new file mode 100644 index 000000000..f4bae1e81 --- /dev/null +++ b/app/controllers/roles_controller.rb @@ -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 --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb new file mode 100644 index 000000000..66a9b674b --- /dev/null +++ b/app/controllers/search_controller.rb @@ -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 --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb new file mode 100644 index 000000000..586c23956 --- /dev/null +++ b/app/controllers/settings_controller.rb @@ -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 --git a/app/controllers/sys_controller.rb b/app/controllers/sys_controller.rb new file mode 100644 index 000000000..b822c5c1e --- /dev/null +++ b/app/controllers/sys_controller.rb @@ -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 --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb new file mode 100644 index 000000000..229fc67ab --- /dev/null +++ b/app/controllers/tags_controller.rb @@ -0,0 +1,77 @@ +# This controller was added by william +class TagsController < ApplicationController + + before_filter :require_admin,:only => :show + include ProjectsHelper + include IssuesHelper + include UsersHelper + include ActsAsTaggableOn::TagsHelper + + $selected_tags = Array.new + $related_tags = Array.new + def index + + $selected_tags = [] + $related_tags = [] + $selected_tags << params[:q] + + @issues_tags_num = Issue.tag_counts.size + @projects_tags_num = Project.tag_counts.size + @users_tags_num = User.tag_counts.size + + @issues_results = get_issues_by_tag($selected_tags) + @projects_results = get_projects_by_tag($selected_tags) + @users_results = get_users_by_tag($selected_tags) + + @obj_id = params[:obj_id] + case params[:object_flag] + when '1' then + @obj = User.find_by_id(@obj_id) + when '2' then + @obj = Project.find_by_id(@obj_id) + when '3' then + @obj = Issue.find_by_id(@obj_id) + else + @obj = nil + end + + unless @obj.nil? + @tags = @obj.tag_list + $selected_tags.each do |i| + @tags.delete(i) + end + $related_tags = @tags + else + return + end + + end + + def add_tag + @tag = params[:tag] + $selected_tags << @tag + $related_tags.delete(@tag) + + @issues_results = get_issues_by_tag($selected_tags) + @projects_results = get_projects_by_tag($selected_tags) + @users_results = get_users_by_tag($selected_tags) + end + + def delete_tag + @tag = params[:tag] + $related_tags << @tag + $selected_tags.delete(@tag) + + @issues_results = get_issues_by_tag($selected_tags) + @projects_results = get_projects_by_tag($selected_tags) + @users_results = get_users_by_tag($selected_tags) + end + + def count(name) + end + + def show + + end + +end diff --git a/app/controllers/test_controller.rb b/app/controllers/test_controller.rb new file mode 100644 index 000000000..2aa5599ef --- /dev/null +++ b/app/controllers/test_controller.rb @@ -0,0 +1,126 @@ +class TestController < ApplicationController + + before_filter :find_user, :only => [:new, :create, :destroy] + + +def index + #@watchers_of_projects = WatchersOfProjects.new + #@watchers_of_projects.user_id = 1 + #@watchers_of_projects.project_id = 1 + #@watchers_of_projects.save + + #测试user表与watch_projectè¡¨ä¹‹é—´çš„å…³è”æ˜¯å¦æˆåŠŸ + #@user = User.find(params[:id]) + #@watch_table = @user.watch_projects.to_a.first + + #@watch = WatchProject.find(1) + #@watcher = @watch.user + + #测试通过watch_project表使user表å¯ä»¥è®¿é—®project表 + #@watch_project = @user.projects + #watch_project_path(@watch) + + #@project = Project.find(11) + #project_path(@project) + #@member = @project.users + #@watched = @project.watch_projects + #@issue = Issue.find(6) + + + #user_path(@user) + #issue_path(@issue) + + #@watcher2=WatchProject.where("#{WatchProject.table_name}.project_id = ?" , temp) + + #测试whereè¯­å¥ + #temp = 1 + #@watcher2=WatchProject.where(:project_id => temp).to_a + + #测试新建记录 + #@watch_new = WatchProject.new + #@watch_new.user_id = 4 + #@watch_new.project_id = 1 + #@watch_new.save + #@id = params[:id] + + #测试添加关注项目功能 + #WatchersOfProjects.watch(3,10) + #Project.find(50) + #测试统计关注该项目的用户数 + #@count = WatchersOfProjects.watcher_count(@watch_project.to_a.first) + #æµ‹è¯•å–æ¶ˆå…³æ³¨åŠŸèƒ½ + #WatchersOfProjects.watch_cancle(10,35) + + #测试关注用户功能 + #测试关注功能 + #WatchersOfUser.watch_user(7,7) + #æµ‹è¯•å–æ¶ˆå…³æ³¨åŠŸèƒ½ + #WatchersOfUser.cancel_watching_user(1,2) + #测试查找关注的人功能 + #@user = WatchersOfUser.find_users(1) + #测试查找被关注的人功能 + #@user = WatchersOfUser.find_watchers(10) + + #测试用户留言功能 + #测试留言功能 + MessagesForUser.leave_message(User.current.id, 6, 'test') + #测试查找留言功能 + #@message_table = MessagesForUser.find_message(3) + #测试查找留言用户功能 + #@messager=@message_table.first.find_messager + + + #测试需求 + #测试新建需求 + #bids = Bid.creat_bids(10000, '2013.7.25', 'test', 'sfsadgfag') + #测试修改需求 + #bids.update_bids(10, '2014.7.222', 'asdf') + #测试删除需求 + # bids = Bid.where('id = ?', 5) + # bids.each do |bid| + # bid.delete_bids + # end + end + + ##########留言功能 message by fq + def new + end + + def create + + if params[:user_search].size>0 + unless params[:user_id].nil? + message = params[:user_search] + MessagesForUser.leave_message(User.current.id, params[:user_id], message) + @message = MessagesForUser.find_message(@user.id) + end + 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 destroy + MessagesForUser.delete_message(params[:object_id]) + @message = MessagesForUser.find_message(@user.id) + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + private + + def find_user + if params[:user_id] + @user = User.find(params[:user_id]) + end + rescue + render_404 + end + #######end of message +end \ No newline at end of file diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb new file mode 100644 index 000000000..92210fff5 --- /dev/null +++ b/app/controllers/timelog_controller.rb @@ -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 --git a/app/controllers/trackers_controller.rb b/app/controllers/trackers_controller.rb new file mode 100644 index 000000000..94131a2e0 --- /dev/null +++ b/app/controllers/trackers_controller.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. + +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 --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 000000000..319608718 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,320 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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 'base_users' + + before_filter :require_admin, :except => [:show, :index,:tag_save] + before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership, :user_activities, :user_projects, :user_newfeedback, :user_comments] + accept_api_auth :index, :show, :create, :update, :destroy + + helper :sort + include SortHelper + helper :custom_fields + include CustomFieldsHelper + include AvatarHelper + + # added by liuping 关注 + + helper :watchers + helper :activities + + ### added by william + include ActsAsTaggableOn::TagsHelper + + + helper :watchers + helper :activities + + # fq + helper :words + #added by young + def user_projects + @message = MessagesForUser.find_message(@user.id) + @memberships = @user.memberships.all(:conditions => Project.visible_condition(User.current)) + + events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 20) + @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 + format.api + end + end + + + def user_activities + #####fq +# @message = MessagesForUser.find_message(@user.id) + # 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 => 30) + @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 + format.api + end + end + + def user_newfeedback + @jour = @user.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + end + + def user_comments + + end + #end + 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 + has = { + "show_changesets" => true + } + # @count = Redmine::Activity::Fetcher.new(User.current, :author => @user).scope_select {|t| !has["show_#{t}"].nil?}.events(nil, nil).count + + + 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 + @user_base_tag = params[:id]?'base_users':'base' + respond_to do |format| + format.html { + @groups = Group.all.sort + render :layout => @user_base_tag + } + format.api + end + end + + def show + #####fq + @message = MessagesForUser.find_message(@user.id) + # 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 + 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 + + ################# added by william + def tag_save + @tags = params[:tag_for_save][:name] + @obj_id = params[:tag_for_save][:object_id] + @obj_flag = params[:tag_for_save][:object_flag] + + case @obj_flag + when '1' then + @obj = User.find_by_id(@obj_id) + when '2' then + @obj = Project.find_by_id(@obj_id) + when '3' then + @obj = Issue.find_by_id(@obj_id) + else + @obj = nil + end + unless @obj.nil? + @obj.tag_list.add(@tags.split(",")) + else + return + end + if @obj.save + ## 执行æˆåŠŸçš„æ“作。 + else + #æ•获异常 + end + respond_to do |format| + format.html + 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 --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb new file mode 100644 index 000000000..f159f7ecc --- /dev/null +++ b/app/controllers/versions_controller.rb @@ -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 --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb new file mode 100644 index 000000000..2f55de2f0 --- /dev/null +++ b/app/controllers/watchers_controller.rb @@ -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 --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb new file mode 100644 index 000000000..23808a27d --- /dev/null +++ b/app/controllers/welcome_controller.rb @@ -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 WelcomeController < ApplicationController + caches_action :robots + + def index + @news = News.latest User.current + @projects = Project.latest User.current + #by young + (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 + + def robots + @projects = Project.all_public.active + render :layout => false, :content_type => 'text/plain' + end +end diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb new file mode 100644 index 000000000..2b7d485f5 --- /dev/null +++ b/app/controllers/wiki_controller.rb @@ -0,0 +1,357 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# 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 + layout 'base_projects' + 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 --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb new file mode 100644 index 000000000..cdd778e48 --- /dev/null +++ b/app/controllers/wikis_controller.rb @@ -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 --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb new file mode 100644 index 000000000..ab7d7f9aa --- /dev/null +++ b/app/controllers/words_controller.rb @@ -0,0 +1,99 @@ +#####leave message fq +class WordsController < ApplicationController + + before_filter :find_user, :only => [:new, :create, :destroy, :more, :back] + + def create + if params[:new_form][:user_message].size>0 + unless params[:user_id].nil? + message = params[:new_form][:user_message] + @user.add_jour(User.current, message) + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + end + end + @jour = @user.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + + 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 destroy + JournalsForMessage.delete_message(params[:object_id]) + @jour = @user.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def new + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @user + text = [] + end + # Replaces pre blocks with [...] + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}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 more + @jour = @user.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def back + @jour = @user.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + private + + def find_user + if params[:user_id] + @user = User.find(params[:user_id]) + end + rescue + render_404 + end + + #######end of message +end \ No newline at end of file diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb new file mode 100644 index 000000000..06ae30e2e --- /dev/null +++ b/app/controllers/workflows_controller.rb @@ -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 --git a/app/helpers/account_helper.rb b/app/helpers/account_helper.rb new file mode 100644 index 000000000..8beeac363 --- /dev/null +++ b/app/helpers/account_helper.rb @@ -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 --git a/app/helpers/activities_helper.rb b/app/helpers/activities_helper.rb new file mode 100644 index 000000000..a5aa247d5 --- /dev/null +++ b/app/helpers/activities_helper.rb @@ -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 --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb new file mode 100644 index 000000000..1f766afa9 --- /dev/null +++ b/app/helpers/admin_helper.rb @@ -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 --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 000000000..fedefeb71 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,1287 @@ +# 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 + include AvatarHelper + + 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]+/, "
").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) + #Modified by nie. + 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 << "\n" * ancestors.size) + @project = original_project + end + s.html_safe + end + #added by young + def render_project_nested_lists_new(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 << "\n" * ancestors.size) + @project = original_project + end + s.html_safe + end + #end + def render_page_hierarchy(pages, node=nil, options={}) + content = '' + if pages[node] + content << "\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 = + ("" + + '').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 ? ' ' * 2 * level + '» ' : '').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 << "\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) << %() + end + unless groups.empty? + s << %(#{groups}) + 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+)}, '\1.\2').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('

'.html_safe + l(:label_export_to)) + yield Redmine::Views::OtherFormatsBuilder.new(self) + concat('

'.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 << "" + 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)>)/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] + "\n#{content}" + 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 = /

\{\{([<>]?)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 = "

' * (current - root) + out << '' + 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+/, "

"). # 2+ newline -> 2 br + gsub(/([^\n]\n)(?=[^\n])/, '\1
'). # 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 << "
    \n" + errors.each do |error| + html << "
  • #{h error}
  • \n" + end + html << "
\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 ') + 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 + "".html_safe + end + + def robot_exclusion_tag + ''.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 + + # Add by Tao + def url_to_avatar(source) + get_avatar(source) + end + # Endof Tao's code + + def date_format_local(time) + date = time.strftime("%Yå¹´%m月%dæ—¥") + 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 --git a/app/helpers/attachments_helper.rb b/app/helpers/attachments_helper.rb new file mode 100644 index 000000000..a4925343f --- /dev/null +++ b/app/helpers/attachments_helper.rb @@ -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 --git a/app/helpers/auth_sources_helper.rb b/app/helpers/auth_sources_helper.rb new file mode 100644 index 000000000..2fa87d5c8 --- /dev/null +++ b/app/helpers/auth_sources_helper.rb @@ -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 --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb new file mode 100644 index 000000000..c17ccadf9 --- /dev/null +++ b/app/helpers/avatar_helper.rb @@ -0,0 +1,52 @@ +module AvatarHelper + + AVATAR_SIZE="50x50" + + def avatar_image(source) + File.join(relative_path, avatar_directory(source.class), source.id.to_s) + end + + def relative_path + "avatars" #File.join("images","avatars") + end + + def storage_path + File.join(Rails.root, "public", "images", relative_path) + end + + def avatar_directory(source_type) + "#{source_type}" + end + + def avatar_filename(source_id,image_file) + "#{source_id}" #<< file_extension(image_file) + end + + def disk_filename(source_type,source_id,image_file=nil) + File.join(storage_path,avatar_directory(source_type),avatar_filename(source_id,image_file)) + end + + def file_extension(filename=nil) + $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$} + end + + def get_avatar(source) + if source.nil? + return File.join(relative_path,'AnonymousUser','0') + end + if File.exist?(disk_filename(source.class,source.id)) + avatar_image(source) + else + File.join(relative_path,avatar_directory(source.class),'0') + end + end + + def get_avatar?(source) + if File.exist?(disk_filename(source.class,source.id)) + return true + else + return false + end + end + +end diff --git a/app/helpers/bids_helper.rb b/app/helpers/bids_helper.rb new file mode 100644 index 000000000..2f2840741 --- /dev/null +++ b/app/helpers/bids_helper.rb @@ -0,0 +1,32 @@ +module BidsHelper + def render_notes(bid, journal, options={}) + content = '' + removable = User.current == journal.user || User.current == bid.author + links = [] + if !journal.notes.blank? + links << link_to(image_tag('comment.png'), + {:controller => 'bids', :action => 'new', :id => bid, :journal_id => journal}, + :remote => true, + :method => 'post', + :title => l(:button_quote)) if options[:reply_links] + if removable + url = {:controller => 'bids', + :action => 'destroy', + :object_id => journal, + :bid_id => bid} + links << ' ' + links << link_to(image_tag('delete.png'), url, + :remote => true, :method => 'delete', :class => "delete", :title => l(:button_delete)) + end + end + content << content_tag('div', links.join(' ').html_safe, :class => 'contextual') unless links.empty? + content << textilizable(journal.notes) + css_classes = "wiki" + 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 \ No newline at end of file diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb new file mode 100644 index 000000000..84b979c44 --- /dev/null +++ b/app/helpers/boards_helper.rb @@ -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 ? ' ' * 2 * level + '» ' : '').html_safe + label << board.name + options << [label, board.id] + end + options + end +end diff --git a/app/helpers/calendars_helper.rb b/app/helpers/calendars_helper.rb new file mode 100644 index 000000000..e57d9e539 --- /dev/null +++ b/app/helpers/calendars_helper.rb @@ -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) = « + 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) = » + 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 --git a/app/helpers/context_menus_helper.rb b/app/helpers/context_menus_helper.rb new file mode 100644 index 000000000..85f88fbe9 --- /dev/null +++ b/app/helpers/context_menus_helper.rb @@ -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 --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb new file mode 100644 index 000000000..803dbb6d3 --- /dev/null +++ b/app/helpers/custom_fields_helper.rb @@ -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 ? " *".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 --git a/app/helpers/documents_helper.rb b/app/helpers/documents_helper.rb new file mode 100644 index 000000000..487ddafd4 --- /dev/null +++ b/app/helpers/documents_helper.rb @@ -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 --git a/app/helpers/enumerations_helper.rb b/app/helpers/enumerations_helper.rb new file mode 100644 index 000000000..bb276429e --- /dev/null +++ b/app/helpers/enumerations_helper.rb @@ -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 --git a/app/helpers/gantt_helper.rb b/app/helpers/gantt_helper.rb new file mode 100644 index 000000000..4f65884a5 --- /dev/null +++ b/app/helpers/gantt_helper.rb @@ -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 --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb new file mode 100644 index 000000000..aa58eb575 --- /dev/null +++ b/app/helpers/groups_helper.rb @@ -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 --git a/app/helpers/issue_categories_helper.rb b/app/helpers/issue_categories_helper.rb new file mode 100644 index 000000000..9189025c3 --- /dev/null +++ b/app/helpers/issue_categories_helper.rb @@ -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 --git a/app/helpers/issue_relations_helper.rb b/app/helpers/issue_relations_helper.rb new file mode 100644 index 000000000..24ae7e36c --- /dev/null +++ b/app/helpers/issue_relations_helper.rb @@ -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 --git a/app/helpers/issue_statuses_helper.rb b/app/helpers/issue_statuses_helper.rb new file mode 100644 index 000000000..b38768654 --- /dev/null +++ b/app/helpers/issue_statuses_helper.rb @@ -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 --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb new file mode 100644 index 000000000..4ecc33690 --- /dev/null +++ b/app/helpers/issues_helper.rb @@ -0,0 +1,383 @@ +# 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" + # + #
<%= link_to_issue(issue) %> + # <%= render_issue_tooltip(issue) %> + #
+ # + 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) + "

".html_safe + + "#{@cached_label_project}: #{link_to_project(issue.project)}
".html_safe + + "#{@cached_label_status}: #{h(issue.status.name)}
".html_safe + + "#{@cached_label_start_date}: #{format_date(issue.start_date)}
".html_safe + + "#{@cached_label_due_date}: #{format_date(issue.due_date)}
".html_safe + + "#{@cached_label_assigned_to}: #{h(issue.assigned_to)}
".html_safe + + "#{@cached_label_priority}: #{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 << '
' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id))) + end + s << '
' + 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 << '
' * (ancestors.size + 1) + s.html_safe + end + + def render_descendants_tree(issue) + s = '
' + 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 << '
' + 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 = "\n" + n = 0 + ordered_values.compact.each do |value| + s << "\n\n" if n > 0 && (n % 2) == 0 + s << "\t#{ h(value.custom_field.name) }:#{ simple_format_without_paragraph(h(show_value(value))) }\n" + n += 1 + end + s << "\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('
').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 + + # this method is used to get all projects that tagged one tag + # added by william + def get_issues_by_tag(tag_name) + Issue.tagged_with(tag_name) + end + +end diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb new file mode 100644 index 000000000..b8e7f8bf9 --- /dev/null +++ b/app/helpers/journals_helper.rb @@ -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 --git a/app/helpers/mail_handler_helper.rb b/app/helpers/mail_handler_helper.rb new file mode 100644 index 000000000..037ea57ee --- /dev/null +++ b/app/helpers/mail_handler_helper.rb @@ -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 --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb new file mode 100644 index 000000000..fcaa62db5 --- /dev/null +++ b/app/helpers/members_helper.rb @@ -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, 10, params['page']#by young + 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('div', content_tag('ul', links), :class => 'pagination') + end +end diff --git a/app/helpers/messages_helper.rb b/app/helpers/messages_helper.rb new file mode 100644 index 000000000..bd2b20a8f --- /dev/null +++ b/app/helpers/messages_helper.rb @@ -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 --git a/app/helpers/my_helper.rb b/app/helpers/my_helper.rb new file mode 100644 index 000000000..9017e9248 --- /dev/null +++ b/app/helpers/my_helper.rb @@ -0,0 +1,72 @@ +# 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 + include AvatarHelper + 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 --git a/app/helpers/news_helper.rb b/app/helpers/news_helper.rb new file mode 100644 index 000000000..a5b8888a9 --- /dev/null +++ b/app/helpers/news_helper.rb @@ -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 --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb new file mode 100644 index 000000000..cbe57d1c7 --- /dev/null +++ b/app/helpers/projects_helper.rb @@ -0,0 +1,91 @@ +# 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 << "" 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? + #Delete by nie. + # s << content_tag('td', 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 + + # this method is used to get all projects that tagged one tag + # added by william + def get_projects_by_tag(tag_name) + Project.tagged_with(tag_name) + end + +end diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb new file mode 100644 index 000000000..2de6b0c90 --- /dev/null +++ b/app/helpers/queries_helper.rb @@ -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 --git a/app/helpers/reports_helper.rb b/app/helpers/reports_helper.rb new file mode 100644 index 000000000..9d52b673f --- /dev/null +++ b/app/helpers/reports_helper.rb @@ -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 --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb new file mode 100644 index 000000000..ae45d2a58 --- /dev/null +++ b/app/helpers/repositories_helper.rb @@ -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', "#{h property}: #{h properties[property]}".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 << '
    ' + 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 << "
  • #{text}" + output << render_changes_tree(s) + output << "
  • " + 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 << "
  • #{text}
  • " + end + end + output << '
' + 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')) + + '
'.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') + ) + + '
'.html_safe + l(:text_mercurial_repository_note)) + + content_tag('p', form.select( + :path_encoding, [nil] + Setting::ENCODINGS, + :label => l(:field_scm_path_encoding) + ) + + '
'.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') + ) + + '
'.html_safe + + l(:text_git_repository_note)) + + content_tag('p', form.select( + :path_encoding, [nil] + Setting::ENCODINGS, + :label => l(:field_scm_path_encoding) + ) + + '
'.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) + ) + + '
'.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) + ) + + '
'.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 --git a/app/helpers/roles_helper.rb b/app/helpers/roles_helper.rb new file mode 100644 index 000000000..44fea58d6 --- /dev/null +++ b/app/helpers/roles_helper.rb @@ -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 --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb new file mode 100644 index 000000000..15c809964 --- /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 --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb new file mode 100644 index 000000000..e44c5f8a9 --- /dev/null +++ b/app/helpers/search_helper.rb @@ -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 + ('
    '.html_safe + + links.map {|link| content_tag('li', link)}.join(' ').html_safe + + '
'.html_safe) unless links.empty? + end +end diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb new file mode 100644 index 000000000..a01e29a3a --- /dev/null +++ b/app/helpers/settings_helper.rb @@ -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 --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb new file mode 100644 index 000000000..13beed3c2 --- /dev/null +++ b/app/helpers/sort_helper.rb @@ -0,0 +1,243 @@ +# encoding: utf-8 +# +# Helpers to sort tables using clickable column headers. +# +# Author: Stuart Rackham , 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): +# +# +# +# <%= 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) %> +# +# +# +# - 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 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 --git a/app/helpers/test_helper.rb b/app/helpers/test_helper.rb new file mode 100644 index 000000000..38f67911b --- /dev/null +++ b/app/helpers/test_helper.rb @@ -0,0 +1,31 @@ +########fq +module TestHelper + def message_list(object) + object = object.reverse + remove_allowed = (User.current.id == object.first.user_id) + content = ''.html_safe + lis = object.each do |t_object| + s = ''.html_safe + s << avatar(t_object.user, :size => "16").to_s + s << link_to_user(t_object.find_messager.first, :class => 'user') + s << ':' + t_object.message + #time = '更新于' + time_tag(t_object.created_at) + '之å‰' + time = time_tag(t_object.created_at) + #s << content_tag('p', l(:field_add, time)) + s << content_tag('div', time) + if remove_allowed + url = {:controller => 'test', + :action => 'destroy', + :object_id => t_object.id, + :user_id => User.current.id} + s << ' ' + s << link_to(image_tag('delete.png'), url, + :remote => true, :method => 'delete', :class => "delete") + end + content << content_tag('li', s, :class => "user-#{t_object.messager_id}") + end + # content.present? ? content_tag('ul', content, :class => 'watchers') : content + content + end +end + \ No newline at end of file diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb new file mode 100644 index 000000000..cf5629f52 --- /dev/null +++ b/app/helpers/timelog_helper.rb @@ -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 --git a/app/helpers/trackers_helper.rb b/app/helpers/trackers_helper.rb new file mode 100644 index 000000000..6b0e7b61e --- /dev/null +++ b/app/helpers/trackers_helper.rb @@ -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 --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 000000000..9b6f85d2a --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,64 @@ +# 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. + + + +include AvatarHelper +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 + + # this method is used to get all projects that tagged one tag + # added by william + def get_users_by_tag(tag_name) + User.tagged_with(tag_name) + end + +end diff --git a/app/helpers/versions_helper.rb b/app/helpers/versions_helper.rb new file mode 100644 index 000000000..61cb382c5 --- /dev/null +++ b/app/helpers/versions_helper.rb @@ -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 --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb new file mode 100644 index 000000000..eef4ab731 --- /dev/null +++ b/app/helpers/watchers_helper.rb @@ -0,0 +1,86 @@ +# 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 + + ###################modified by liuping + 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 = (objects.first.instance_of?(User) or objects.first.instance_of?(Project)) ? + (watched ? l(:button_unfollow) : l(:button_follow)) : (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 --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb new file mode 100644 index 000000000..002bc470f --- /dev/null +++ b/app/helpers/welcome_helper.rb @@ -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 --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb new file mode 100644 index 000000000..c6cb3b39d --- /dev/null +++ b/app/helpers/wiki_helper.rb @@ -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) ? (' ' * level * 2 + '» ') : '' + + 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 --git a/app/helpers/words_helper.rb b/app/helpers/words_helper.rb new file mode 100644 index 000000000..167c78e2c --- /dev/null +++ b/app/helpers/words_helper.rb @@ -0,0 +1,47 @@ +########fq +module WordsHelper + def message_list(object, state, user) + unless state + if object.size > 5 + object = object[-5, 5] + end + end + object = object.reverse + remove_allowed = (User.current.id == object.first.user_id) + content = ''.html_safe + lis = object.each do |t_object| + s = ''.html_safe + s << link_to(t_object.indice, {}, :class => "journal-link") + s << avatar(t_object.user, :size => "16").to_s + s << link_to_user(t_object.user, :class => 'user') + time = time_tag(t_object.created_at) + s << l(:field_add, :time => time).html_safe + if !t_object.notes.blank? + s << link_to(image_tag('comment.png'), + {:controller => 'words', :action => 'new', :id => user, :journal_id => t_object}, + :remote => true, + :method => 'post', + :title => l(:button_quote)) + if remove_allowed || t_object.jour_id == User.current.id + url = {:controller => 'words', + :action => 'destroy', + :object_id => t_object, + :user_id => user} + s << ' ' + s << link_to(image_tag('delete.png'), url, + :remote => true, :method => 'delete', :class => "delete", :title => l(:button_delete)) + end + end + #time = '更新于' + time_tag(t_object.created_at) + '之å‰' + + + # s << content_tag('div', time) + + content << content_tag('li', s, :class => "user-#{t_object.jour_id}") + content << textilizable(t_object.notes) + end + # content.present? ? content_tag('ul', content, :class => 'watchers') : content + content + end +end + \ No newline at end of file diff --git a/app/helpers/workflows_helper.rb b/app/helpers/workflows_helper.rb new file mode 100644 index 000000000..1cec67a88 --- /dev/null +++ b/app/helpers/workflows_helper.rb @@ -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 --git a/app/models/attachment.rb b/app/models/attachment.rb new file mode 100644 index 000000000..eeab56242 --- /dev/null +++ b/app/models/attachment.rb @@ -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 --git a/app/models/auth_source.rb b/app/models/auth_source.rb new file mode 100644 index 000000000..0b4db9bcc --- /dev/null +++ b/app/models/auth_source.rb @@ -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 --git a/app/models/auth_source_ldap.rb b/app/models/auth_source_ldap.rb new file mode 100644 index 000000000..25cdc6f1b --- /dev/null +++ b/app/models/auth_source_ldap.rb @@ -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 --git a/app/models/bid.rb b/app/models/bid.rb new file mode 100644 index 000000000..f7c599c94 --- /dev/null +++ b/app/models/bid.rb @@ -0,0 +1,58 @@ +####by fq +class Bid < ActiveRecord::Base + #attr_accessible :author_id, :budget, :deadline, :name, :description + + belongs_to :author, :class_name => 'User', :foreign_key => :author_id + has_many :biding_projects, :dependent => :destroy + has_many :projects, :through => :biding_projects + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + + NAME_LENGTH_LIMIT = 60 + DESCRIPTION_LENGTH_LIMIT = 250 + + validates_length_of :name, :maximum => NAME_LENGTH_LIMIT + validates_length_of :description, :maximum => DESCRIPTION_LENGTH_LIMIT + validates_presence_of :author_id, :name + validate :validate_user + + acts_as_watchable + acts_as_taggable + + + def add_jour(user, notes) + self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes) + end + + def self.creat_bids(budget, deadline, name, description=nil) + self.create(:author_id => User.current.id, :budget => budget, + :deadline => deadline, :name => name, :description => description, :commit => 0) + end + + def update_bids(budget, deadline, name, description=nil) + if(User.current.id == self.author_id) + self.name = name + self.budget = budget + self.deadline = deadline + self.description = description + self.save + end + end + + def delete_bids + unless self.nil? + if User.current.id == self.author_id + self.destroy + end + end + end + + def set_commit(commit) + self.update_attribute(:commit, commit) + end + + private + + def validate_user + errors.add :author_id, :invalid if author.nil? || !author.active? + end +end diff --git a/app/models/biding_project.rb b/app/models/biding_project.rb new file mode 100644 index 000000000..e9cd6560d --- /dev/null +++ b/app/models/biding_project.rb @@ -0,0 +1,44 @@ +class BidingProject < ActiveRecord::Base + attr_accessible :bid_id, :project_id, :user_id, :description + + belongs_to :bid + belongs_to :project + belongs_to :user + + DESCRIPTION_LENGTH_LIMIT = 500 + + validates_length_of :description, :maximum => DESCRIPTION_LENGTH_LIMIT + validates_presence_of :user_id, :bid_id, :project_id + validate :validate_user + validate :validate_bid + validate :validate_project + validates_uniqueness_of :bid_id, :scope => :project_id + + def self.cerate_bidding(bid_id, project_id, description = nil) + self.create(:user_id => User.current.id, :bid_id => bid_id, + :project_id => project_id, :description => description) + end + + def cancel_bidding + unless self.nil? + if User.current.id == self.user_id + self.destroy + end + end + end + + private + + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + def validate_bid + errors.add :bid_id, :invalid if bid.nil? + end + + def validate_project + errors.add :project_id, :invalid if project.nil? + end + +end diff --git a/app/models/board.rb b/app/models/board.rb new file mode 100644 index 000000000..cb81e0a5a --- /dev/null +++ b/app/models/board.rb @@ -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 --git a/app/models/change.rb b/app/models/change.rb new file mode 100644 index 000000000..b80b96eb9 --- /dev/null +++ b/app/models/change.rb @@ -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 --git a/app/models/changeset.rb b/app/models/changeset.rb new file mode 100644 index 000000000..d3fa8ab2b --- /dev/null +++ b/app/models/changeset.rb @@ -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 --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 000000000..577afe942 --- /dev/null +++ b/app/models/comment.rb @@ -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 --git a/app/models/comment_observer.rb b/app/models/comment_observer.rb new file mode 100644 index 000000000..e7c12c4b6 --- /dev/null +++ b/app/models/comment_observer.rb @@ -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 --git a/app/models/custom_field.rb b/app/models/custom_field.rb new file mode 100644 index 000000000..c15192388 --- /dev/null +++ b/app/models/custom_field.rb @@ -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 --git a/app/models/custom_field_value.rb b/app/models/custom_field_value.rb new file mode 100644 index 000000000..04288b117 --- /dev/null +++ b/app/models/custom_field_value.rb @@ -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 --git a/app/models/custom_value.rb b/app/models/custom_value.rb new file mode 100644 index 000000000..62bbc8108 --- /dev/null +++ b/app/models/custom_value.rb @@ -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 --git a/app/models/document.rb b/app/models/document.rb new file mode 100644 index 000000000..0c2ce1736 --- /dev/null +++ b/app/models/document.rb @@ -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 --git a/app/models/document_category.rb b/app/models/document_category.rb new file mode 100644 index 000000000..95aa57304 --- /dev/null +++ b/app/models/document_category.rb @@ -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 --git a/app/models/document_category_custom_field.rb b/app/models/document_category_custom_field.rb new file mode 100644 index 000000000..a95c55a4d --- /dev/null +++ b/app/models/document_category_custom_field.rb @@ -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 --git a/app/models/document_observer.rb b/app/models/document_observer.rb new file mode 100644 index 000000000..4a61f1184 --- /dev/null +++ b/app/models/document_observer.rb @@ -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 --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb new file mode 100644 index 000000000..94539ec00 --- /dev/null +++ b/app/models/enabled_module.rb @@ -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 --git a/app/models/enumeration.rb b/app/models/enumeration.rb new file mode 100644 index 000000000..1946735ec --- /dev/null +++ b/app/models/enumeration.rb @@ -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 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 :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 --git a/app/models/group.rb b/app/models/group.rb new file mode 100644 index 000000000..d1b2cb966 --- /dev/null +++ b/app/models/group.rb @@ -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 --git a/app/models/group_custom_field.rb b/app/models/group_custom_field.rb new file mode 100644 index 000000000..982741380 --- /dev/null +++ b/app/models/group_custom_field.rb @@ -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 --git a/app/models/issue.rb b/app/models/issue.rb new file mode 100644 index 000000000..5ecadb672 --- /dev/null +++ b/app/models/issue.rb @@ -0,0 +1,1443 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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 + +###########################added by william + acts_as_taggable + + 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 --git a/app/models/issue_category.rb b/app/models/issue_category.rb new file mode 100644 index 000000000..6efec6a5d --- /dev/null +++ b/app/models/issue_category.rb @@ -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 --git a/app/models/issue_custom_field.rb b/app/models/issue_custom_field.rb new file mode 100644 index 000000000..e7ea9c0b3 --- /dev/null +++ b/app/models/issue_custom_field.rb @@ -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 --git a/app/models/issue_observer.rb b/app/models/issue_observer.rb new file mode 100644 index 000000000..a75194286 --- /dev/null +++ b/app/models/issue_observer.rb @@ -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 --git a/app/models/issue_priority.rb b/app/models/issue_priority.rb new file mode 100644 index 000000000..fa5a29c8a --- /dev/null +++ b/app/models/issue_priority.rb @@ -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 --git a/app/models/issue_priority_custom_field.rb b/app/models/issue_priority_custom_field.rb new file mode 100644 index 000000000..5a691175c --- /dev/null +++ b/app/models/issue_priority_custom_field.rb @@ -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 --git a/app/models/issue_query.rb b/app/models/issue_query.rb new file mode 100644 index 000000000..5b818cc28 --- /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 --git a/app/models/issue_relation.rb b/app/models/issue_relation.rb new file mode 100644 index 000000000..9e5015644 --- /dev/null +++ b/app/models/issue_relation.rb @@ -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 --git a/app/models/issue_status.rb b/app/models/issue_status.rb new file mode 100644 index 000000000..0e8c9ea94 --- /dev/null +++ b/app/models/issue_status.rb @@ -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 --git a/app/models/journal.rb b/app/models/journal.rb new file mode 100644 index 000000000..a75c112db --- /dev/null +++ b/app/models/journal.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. + +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 --git a/app/models/journal_detail.rb b/app/models/journal_detail.rb new file mode 100644 index 000000000..1ec195733 --- /dev/null +++ b/app/models/journal_detail.rb @@ -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 --git a/app/models/journal_observer.rb b/app/models/journal_observer.rb new file mode 100644 index 000000000..fe937de07 --- /dev/null +++ b/app/models/journal_observer.rb @@ -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 --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb new file mode 100644 index 000000000..8b99b9896 --- /dev/null +++ b/app/models/journals_for_message.rb @@ -0,0 +1,12 @@ +class JournalsForMessage < ActiveRecord::Base + attr_accessible :jour_id, :jour_type, :notes, :reply_id, :status, :user_id + attr_accessor :indice + + belongs_to :jour, :polymorphic => true + belongs_to :user + + def self.delete_message(message_id) + self.delete_all "id = #{message_id}" + end + +end diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb new file mode 100644 index 000000000..8421fb67d --- /dev/null +++ b/app/models/mail_handler.rb @@ -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{^ 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{^$/) + 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 --git a/app/models/mailer.rb b/app/models/mailer.rb new file mode 100644 index 000000000..7166025c2 --- /dev/null +++ b/app/models/mailer.rb @@ -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 --git a/app/models/member.rb b/app/models/member.rb new file mode 100644 index 000000000..b11086061 --- /dev/null +++ b/app/models/member.rb @@ -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 --git a/app/models/member_role.rb b/app/models/member_role.rb new file mode 100644 index 000000000..29ad6563d --- /dev/null +++ b/app/models/member_role.rb @@ -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 --git a/app/models/message.rb b/app/models/message.rb new file mode 100644 index 000000000..767223748 --- /dev/null +++ b/app/models/message.rb @@ -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 --git a/app/models/message_observer.rb b/app/models/message_observer.rb new file mode 100644 index 000000000..9ef52b6b4 --- /dev/null +++ b/app/models/message_observer.rb @@ -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 --git a/app/models/messages_for_bids.rb b/app/models/messages_for_bids.rb new file mode 100644 index 000000000..d33555538 --- /dev/null +++ b/app/models/messages_for_bids.rb @@ -0,0 +1,3 @@ +class MessagesForBids < ActiveRecord::Base + attr_accessible :bid_id, :message, :user_id +end diff --git a/app/models/messages_for_user.rb b/app/models/messages_for_user.rb new file mode 100644 index 000000000..af3b6863f --- /dev/null +++ b/app/models/messages_for_user.rb @@ -0,0 +1,50 @@ +class MessagesForUser < ActiveRecord::Base + attr_accessible :message, :messager_id, :user_id + belongs_to :user + + MESSAGE_LENGTH_LIMIT = 60 + + validate :validate_user + validate :validate_messager + validates_presence_of :messager_id, :user_id, :message + validates_length_of :message, :maximum => MESSAGE_LENGTH_LIMIT + + def self.leave_message(messager_id, user_id, message) + unless messager_id == user_id + @messages_for_user = self.new + @messages_for_user.messager_id = messager_id + @messages_for_user.user_id = user_id + @messages_for_user.message = message + @messages_for_user.save + true + else + false + end + end + + def self.find_message(user_id) + user = User.find(user_id) + @message_table_for_user = user.messages_for_users.to_a + @message_table_for_user + end + + def find_messager + @messager = User.where(:id =>messager_id) + @messager + end + + def self.delete_message(message_id) + MessagesForUser.delete_all "id = #{message_id}" + end + + #验è¯user是å¦å­˜åœ¨ + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + #验è¯messager是å¦å­˜åœ¨ + def validate_messager + user = User.where("id = ?", messager_id).to_a.first + errors.add :messager_id, :invalid if user.nil? || !user.active? + end +end diff --git a/app/models/news.rb b/app/models/news.rb new file mode 100644 index 000000000..c8a4112cc --- /dev/null +++ b/app/models/news.rb @@ -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 --git a/app/models/news_observer.rb b/app/models/news_observer.rb new file mode 100644 index 000000000..8ba3894f4 --- /dev/null +++ b/app/models/news_observer.rb @@ -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 --git a/app/models/principal.rb b/app/models/principal.rb new file mode 100644 index 000000000..b6f41d535 --- /dev/null +++ b/app/models/principal.rb @@ -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 --git a/app/models/project.rb b/app/models/project.rb new file mode 100644 index 000000000..7cc3100e7 --- /dev/null +++ b/app/models/project.rb @@ -0,0 +1,1040 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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' + + #添加用户关注项目功能 fq + has_many :watchers, :through => :watchers_of_projects, :class_name => 'User' + has_many :watchers_of_projects, :class_name => 'WatchersOfProjects' + #end + + has_many :tags, :through => :project_tags, :class_name => 'Tag' + has_many :project_tags, :class_name => 'ProjectTags' + + 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 + ############################added by william + acts_as_taggable + + ###################added by liuping 关注 + acts_as_watchable + + 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('created_on 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 + # 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 --git a/app/models/project_custom_field.rb b/app/models/project_custom_field.rb new file mode 100644 index 000000000..0c56a25f4 --- /dev/null +++ b/app/models/project_custom_field.rb @@ -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 --git a/app/models/project_tags.rb b/app/models/project_tags.rb new file mode 100644 index 000000000..16de1ea45 --- /dev/null +++ b/app/models/project_tags.rb @@ -0,0 +1,45 @@ +#æ·»åŠ ä»£ç  +class ProjectTags < ActiveRecord::Base + attr_accessible :description, :project_id, :tag_id, :user_id +####################################################################################################æ·»åŠ ä»£ç  + belongs_to :project + belongs_to :tag + belongs_to :user + + validates_uniqueness_of :project_id, :scope => :tag_id + validates_presence_of :project_id, :tag_id, :user_id + validate :validate_user + + + #新建project_tag的内容 + def self.add_tag(project_id, content, description=nil, user_id) + if Tag.add_content(content) #tag表里新建一æ¡è®°å½•和内容字段 + @new_tag = self.new #相应的在project_tags表里新建一æ¡å¯¹åº”的记录 + @new_tag.project_id = project_id + @new_tag.description = description + @t_tag = Tag.where("content = ?", content).to_a #把新添加content的那æ¡è®°å½•的数组返回 + @new_tag.tag_id = @t_tag.first.id #必须用firstæ¥è°ƒç”¨æ•°ç»„第一个元素 + @new_tag.user_id = user_id + @new_tag.save + true + end + end + + #æ ¹æ®project_id查询tag + def self.find_tag(project_id) + @project = Project.find(project_id) + @project_tags = @project.project_tags + @project_tags + end + + def find_tag + @tag = self.tags + @tag + end + + def validate_user + errors.add :user_id, :invalid unless user.nil? || user.active? + end + +end +##################################################################################################### æ·»åŠ ç»“æŸ diff --git a/app/models/query.rb b/app/models/query.rb new file mode 100644 index 000000000..db6ca07a5 --- /dev/null +++ b/app/models/query.rb @@ -0,0 +1,828 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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, + " :label_in_less_than, + ">t+" => :label_in_more_than, + "> :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, + " :label_more_than_ago, + "> :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-", " [ "=", "~", "!", "!~", "!*", "*" ], + :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+", " '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 + "#{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 " + + 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 + 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-" + # >= 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, value.first.to_i, nil) + when "= 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 --git a/app/models/repository.rb b/app/models/repository.rb new file mode 100644 index 000000000..b0e946365 --- /dev/null +++ b/app/models/repository.rb @@ -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 --git a/app/models/repository/bazaar.rb b/app/models/repository/bazaar.rb new file mode 100644 index 000000000..ea20fe37d --- /dev/null +++ b/app/models/repository/bazaar.rb @@ -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 --git a/app/models/repository/cvs.rb b/app/models/repository/cvs.rb new file mode 100644 index 000000000..155ac10ed --- /dev/null +++ b/app/models/repository/cvs.rb @@ -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 --git a/app/models/repository/darcs.rb b/app/models/repository/darcs.rb new file mode 100644 index 000000000..49cbb0e8f --- /dev/null +++ b/app/models/repository/darcs.rb @@ -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 --git a/app/models/repository/filesystem.rb b/app/models/repository/filesystem.rb new file mode 100644 index 000000000..bb5092e33 --- /dev/null +++ b/app/models/repository/filesystem.rb @@ -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 --git a/app/models/repository/git.rb b/app/models/repository/git.rb new file mode 100644 index 000000000..c1f0020eb --- /dev/null +++ b/app/models/repository/git.rb @@ -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 --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb new file mode 100644 index 000000000..79a001e41 --- /dev/null +++ b/app/models/repository/mercurial.rb @@ -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 --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb new file mode 100644 index 000000000..68853a3cf --- /dev/null +++ b/app/models/repository/subversion.rb @@ -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 --git a/app/models/role.rb b/app/models/role.rb new file mode 100644 index 000000000..c7f9306b3 --- /dev/null +++ b/app/models/role.rb @@ -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 --git a/app/models/setting.rb b/app/models/setting.rb new file mode 100644 index 000000000..dab6ceaa7 --- /dev/null +++ b/app/models/setting.rb @@ -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 --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 000000000..b6faeda5b --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,19 @@ +class Tag < ActiveRecord::Base + attr_accessible :content +#æ·»åŠ ä»£ç  + has_many :projects, :through => :project_tags + has_many :project_tags, :class_name => 'ProjectTags' + + #确定contentä¸ä¼šè¢«é‡å¤å†™å…¥ + validates_uniqueness_of :content + validates_presence_of :content + + #添加tag内容 + def self.add_content(content) + @tag=Tag.new + @tag.content = content + @tag.save + true + end +end +#æ·»åŠ ç»“æŸ \ No newline at end of file diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb new file mode 100644 index 000000000..76200e09f --- /dev/null +++ b/app/models/time_entry.rb @@ -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 --git a/app/models/time_entry_activity.rb b/app/models/time_entry_activity.rb new file mode 100644 index 000000000..f2a18d1d0 --- /dev/null +++ b/app/models/time_entry_activity.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. + +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 --git a/app/models/time_entry_activity_custom_field.rb b/app/models/time_entry_activity_custom_field.rb new file mode 100644 index 000000000..9e68526d3 --- /dev/null +++ b/app/models/time_entry_activity_custom_field.rb @@ -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 --git a/app/models/time_entry_custom_field.rb b/app/models/time_entry_custom_field.rb new file mode 100644 index 000000000..df3aed62a --- /dev/null +++ b/app/models/time_entry_custom_field.rb @@ -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 --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb new file mode 100644 index 000000000..f0301ce32 --- /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 --git a/app/models/token.rb b/app/models/token.rb new file mode 100644 index 000000000..3131bce8d --- /dev/null +++ b/app/models/token.rb @@ -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 --git a/app/models/tracker.rb b/app/models/tracker.rb new file mode 100644 index 000000000..d487de67e --- /dev/null +++ b/app/models/tracker.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 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 --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..e4667f720 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,737 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# 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 + + # 添加用户关注项目功能 fq + has_many :projects, :through => :watchers_of_projects + has_many :watchers_of_projects, :class_name => 'WatchersOfProjects' + # end of + + # 添加关注用户功能 fq + has_many :watchers_of_users + # end of + + #添加用户留言功能 fq + has_many :messages_for_users + #end +#####fq + has_many :jours, :class_name => 'JournalsForMessage', :dependent => :destroy + has_many :bids, :dependent => :destroy + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + ##### + + + 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 + ############################added by william + acts_as_taggable + + ############################# added by liuping 关注 + acts_as_watchable + + 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 add_jour(user, notes) + self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes) + end + + 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 --git a/app/models/user_custom_field.rb b/app/models/user_custom_field.rb new file mode 100644 index 000000000..bbcb957da --- /dev/null +++ b/app/models/user_custom_field.rb @@ -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 --git a/app/models/user_extension.rb b/app/models/user_extension.rb new file mode 100644 index 000000000..cdfad28c6 --- /dev/null +++ b/app/models/user_extension.rb @@ -0,0 +1,11 @@ +class UserExtension < ActiveRecord::Base + attr_accessible :birthday, :brief_introduction, :fans_num, :finish_project_num, :follow_num, :gender, :good_num, :location, :occupation, :publish_requirement_num, :user_id, :work_experience, :zip_code + + belongs_to :user + validate :validate_user + + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? || User.current != user_id + end + +end diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb new file mode 100644 index 000000000..5b95386be --- /dev/null +++ b/app/models/user_preference.rb @@ -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 --git a/app/models/version.rb b/app/models/version.rb new file mode 100644 index 000000000..0e11371ad --- /dev/null +++ b/app/models/version.rb @@ -0,0 +1,289 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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' + + # 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 --git a/app/models/version_custom_field.rb b/app/models/version_custom_field.rb new file mode 100644 index 000000000..12bdbdf3d --- /dev/null +++ b/app/models/version_custom_field.rb @@ -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 --git a/app/models/watcher.rb b/app/models/watcher.rb new file mode 100644 index 000000000..1cea711b7 --- /dev/null +++ b/app/models/watcher.rb @@ -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 --git a/app/models/watchers_of_projects.rb b/app/models/watchers_of_projects.rb new file mode 100644 index 000000000..53aca680d --- /dev/null +++ b/app/models/watchers_of_projects.rb @@ -0,0 +1,46 @@ +class WatchersOfProjects < ActiveRecord::Base + attr_accessible :project_id, :user_id + belongs_to :project + belongs_to :user + + validate :validate_user + validate :validate_project + validates_uniqueness_of :user_id, :scope => :project_id + validates_presence_of :user_id, :project_id + + def self.watch(user_id, project_id) + @new_watch = WatchersOfProjects.new + @new_watch.user_id = user_id + @new_watch.project_id = project_id + @new_watch.save + true + end + + def self.watcher_count(project) + @project = project + @count = @project.watchers_of_projects.count + @count + end + + def self.is_watched(user_id, project_id) + @is_watched = self.where("user_id = ? and project_id = ?", user_id, project_id).to_a.first + if @is_watched.nil? + false + else + true + end + end + + def self.watch_cancle(user_id, project_id) + self.delete_all(["user_id = ? and project_id = ?", user_id, project_id]) + true + end + + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + def validate_project + errors.add :project_id, :invalid if project.nil? + end +end diff --git a/app/models/watchers_of_user.rb b/app/models/watchers_of_user.rb new file mode 100644 index 000000000..cf205b1d8 --- /dev/null +++ b/app/models/watchers_of_user.rb @@ -0,0 +1,65 @@ +class WatchersOfUser < ActiveRecord::Base + attr_accessible :user_id, :watcher_id + belongs_to :user + + validates_uniqueness_of :watcher_id, :scope => :user_id + validate :validate_user + validate :validate_watcher + validates_presence_of :watcher_id, :user_id + + def self.watch_user(watcher_id, user_id) + unless user_id == watcher_id + @watchers_of_user = WatchersOfUser.new + @watchers_of_user.watcher_id = watcher_id + @watchers_of_user.user_id = user_id + @watchers_of_user.save + true + else + false + end + end + + def cancel_watching_user + self.class.cancel_watching_user(self.watcher_id, self.user_id) + end + + def self.cancel_watching_user(watcher_id, user_id) + self.delete_all(["user_id = ? and watcher_id = ?", user_id, watcher_id]) + true + end + + def self.find_users(watcher_id) + @user = WatchersOfUser.find_by_sql("select * from users where id in (select user_id from #{WatchersOfUser.table_name} where watcher_id = #{watcher_id})") + @user + # @watch_table_for_user=WatchersOfUser.where(:watcher_id => watcher_id) + # @user = [] + # @watch_table_for_user.each do |watch| + # @user.push(watch.user) + # end + # @user + end + + def self.find_watchers(user_id) + @watcher = WatchersOfUser.find_by_sql("select * from users where id in (select watcher_id from #{WatchersOfUser.table_name} where user_id = #{user_id})") + @watcher + # user = User.find(user_id) + # @watch_table_for_watcher = user.watchers_of_users + # @watcher = [] + # @watch_table_for_watcher.each do |watch| + # user_temp = User.find(watch.watcher_id) + # @watcher.push(user_temp) + # end + # @watcher + end + + #验è¯user是å¦å­˜åœ¨ + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + #验è¯watcher是å¦å­˜åœ¨ + def validate_watcher + user = User.where("id = ?", watcher_id).to_a.first + errors.add :watcher_id, :invalid if user.nil? || !user.active? + end +end diff --git a/app/models/wiki.rb b/app/models/wiki.rb new file mode 100644 index 000000000..d58212d68 --- /dev/null +++ b/app/models/wiki.rb @@ -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 --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb new file mode 100644 index 000000000..a9ed005bc --- /dev/null +++ b/app/models/wiki_content.rb @@ -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 --git a/app/models/wiki_content_observer.rb b/app/models/wiki_content_observer.rb new file mode 100644 index 000000000..6219f407b --- /dev/null +++ b/app/models/wiki_content_observer.rb @@ -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 --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb new file mode 100644 index 000000000..c17fa75d7 --- /dev/null +++ b/app/models/wiki_page.rb @@ -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 --git a/app/models/wiki_redirect.rb b/app/models/wiki_redirect.rb new file mode 100644 index 000000000..da92abb9a --- /dev/null +++ b/app/models/wiki_redirect.rb @@ -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 --git a/app/models/workflow_permission.rb b/app/models/workflow_permission.rb new file mode 100644 index 000000000..c6c0f19d0 --- /dev/null +++ b/app/models/workflow_permission.rb @@ -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 --git a/app/models/workflow_rule.rb b/app/models/workflow_rule.rb new file mode 100644 index 000000000..14e186f16 --- /dev/null +++ b/app/models/workflow_rule.rb @@ -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 --git a/app/models/workflow_transition.rb b/app/models/workflow_transition.rb new file mode 100644 index 000000000..a8fd545ac --- /dev/null +++ b/app/models/workflow_transition.rb @@ -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 --git a/app/sweepers/NOTEMPTY b/app/sweepers/NOTEMPTY new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/account/login.html.erb b/app/views/account/login.html.erb new file mode 100644 index 000000000..05a9f61f7 --- /dev/null +++ b/app/views/account/login.html.erb @@ -0,0 +1,47 @@ +<%= call_hook :view_account_login_top %> +
+<%= form_tag(signin_path) do %> +<%= back_url_hidden_field_tag %> + + + + + + + + + +<% if Setting.openid? %> + + + + +<% end %> + + + + + + + + +
<%= text_field_tag 'username', params[:username], :tabindex => '1' %>
<%= password_field_tag 'password', nil, :tabindex => '2' %>
<%= text_field_tag "openid_url", nil, :tabindex => '3' %>
+ <% if Setting.autologin? %> + + <% end %> +
+ <% if Setting.lost_password? %> + <%= link_to l(:label_password_lost), lost_password_path %> + <% end %> + + +
+<% end %> +
+<%= call_hook :view_account_login_bottom %> + +<% if params[:username].present? %> +<%= javascript_tag "$('#password').focus();" %> +<% else %> +<%= javascript_tag "$('#username').focus();" %> +<% end %> diff --git a/app/views/account/logout.html.erb b/app/views/account/logout.html.erb new file mode 100644 index 000000000..309597603 --- /dev/null +++ b/app/views/account/logout.html.erb @@ -0,0 +1,3 @@ +<%= form_tag(signout_path) do %> +

<%= submit_tag l(:label_logout) %>

+<% end %> diff --git a/app/views/account/lost_password.html.erb b/app/views/account/lost_password.html.erb new file mode 100644 index 000000000..ceb387e03 --- /dev/null +++ b/app/views/account/lost_password.html.erb @@ -0,0 +1,11 @@ +

<%=l(:label_password_lost)%>

+ +<%= form_tag(lost_password_path) do %> +
+

+ + <%= text_field_tag 'mail', nil, :size => 40 %> + <%= submit_tag l(:button_submit) %> +

+
+<% end %> diff --git a/app/views/account/password_recovery.html.erb b/app/views/account/password_recovery.html.erb new file mode 100644 index 000000000..ff455f325 --- /dev/null +++ b/app/views/account/password_recovery.html.erb @@ -0,0 +1,20 @@ +

<%=l(:label_password_lost)%>

+ +<%= error_messages_for 'user' %> + +<%= form_tag(lost_password_path) do %> + <%= hidden_field_tag 'token', @token.value %> +
+

+ + <%= password_field_tag 'new_password', nil, :size => 25 %> + <%= l(:text_caracters_minimum, :count => Setting.password_min_length) %> +

+ +

+ + <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %> +

+
+

<%= submit_tag l(:button_save) %>

+<% end %> diff --git a/app/views/account/register.html.erb b/app/views/account/register.html.erb new file mode 100644 index 000000000..6928f6171 --- /dev/null +++ b/app/views/account/register.html.erb @@ -0,0 +1,31 @@ +

<%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %>

+ +<%= labelled_form_for @user, :url => register_path do |f| %> +<%= error_messages_for 'user' %> + +
+<% if @user.auth_source_id.nil? %> +

<%= f.text_field :login, :size => 25, :required => true %>

+ +

<%= f.password_field :password, :size => 25, :required => true %> + <%= l(:text_caracters_minimum, :count => Setting.password_min_length) %>

+ +

<%= f.password_field :password_confirmation, :size => 25, :required => true %>

+<% end %> + +

<%= f.text_field :firstname, :required => true %>

+

<%= f.text_field :lastname, :required => true %>

+

<%= f.text_field :mail, :required => true %>

+

<%= f.select :language, lang_options_for_select %>

+ +<% if Setting.openid? %> +

<%= f.text_field :identity_url %>

+<% end %> + +<% @user.custom_field_values.select {|v| v.editable? || v.required?}.each do |value| %> +

<%= custom_field_tag_with_label :user, value %>

+<% end %> +
+ +<%= submit_tag l(:button_submit) %> +<% end %> diff --git a/app/views/activities/index.html.erb b/app/views/activities/index.html.erb new file mode 100644 index 000000000..6cc8282e8 --- /dev/null +++ b/app/views/activities/index.html.erb @@ -0,0 +1,142 @@ +

<%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %>

+

+ <%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %> +

+ + + + + + +
+ <% @events_by_day.keys.sort.reverse.each do |day| %> +

+
+ <% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%> +
+ + + + + +
+ + + + + + + + + + +
<%= h(e.project) if @project.nil? || @project != e.project %> æœ‰äº†æœ€æ–°åŠ¨æ€ <%= link_to format_activity_title(e.event_title), e.event_url %>

<%= format_activity_description(e.event_description) %>

<%= format_activity_day(day) %> <%= format_time(e.event_datetime, false) %><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %>
+
+ <% end -%> +
+ <% end -%> +
+ + + + + + + + +<%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %> + +
+ <%= 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))) %> +
+
+ <%= 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 %> +
+<% 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 %> +

<%= l(:label_activity) %>

+

+ <% @activity.event_types.each do |t| %> + <%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %> + +
+ <% end %> +

+<% if @project && @project.descendants.active.any? %> +<%= hidden_field_tag 'with_subprojects', 0 %> +

+ +

+<% end %> +<%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %> +

+ <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %> +

+<% end %> +<% end %> + +<% html_title(l(:label_activity), @author) -%> diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb new file mode 100644 index 000000000..2ac62c2f3 --- /dev/null +++ b/app/views/admin/_menu.html.erb @@ -0,0 +1,3 @@ +
+ <%= render_menu :admin_menu %> +
diff --git a/app/views/admin/_no_data.html.erb b/app/views/admin/_no_data.html.erb new file mode 100644 index 000000000..8ad39b197 --- /dev/null +++ b/app/views/admin/_no_data.html.erb @@ -0,0 +1,8 @@ +
+<%= form_tag({:action => 'default_configuration'}) do %> + <%= simple_format(l(:text_no_configuration_data)) %> +

<%= 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) %>

+<% end %> +
diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb new file mode 100644 index 000000000..8c7ca2b93 --- /dev/null +++ b/app/views/admin/index.html.erb @@ -0,0 +1,8 @@ +

<%=l(:label_administration)%>

+ +
+ <%= render :partial => 'no_data' if @no_configuration_data %> + <%= render :partial => 'menu' %> +
+ +<% html_title(l(:label_administration)) -%> diff --git a/app/views/admin/info.html.erb b/app/views/admin/info.html.erb new file mode 100644 index 000000000..1148efb5e --- /dev/null +++ b/app/views/admin/info.html.erb @@ -0,0 +1,19 @@ +

<%=l(:label_information_plural)%>

+ +

<%= Redmine::Info.versioned_name %>

+ + +<% @checklist.each do |label, result| %> + + + + +<% end %> +
<%= l(label) %><%= image_tag((result ? 'true.png' : 'exclamation.png'), + :style => "vertical-align:bottom;") %>
+
+
+
<%= Redmine::Info.environment %>
+
+ +<% html_title(l(:label_information_plural)) -%> diff --git a/app/views/admin/plugins.html.erb b/app/views/admin/plugins.html.erb new file mode 100644 index 000000000..a573ae63c --- /dev/null +++ b/app/views/admin/plugins.html.erb @@ -0,0 +1,19 @@ +

<%= l(:label_plugins) %>

+ +<% if @plugins.any? %> + + <% @plugins.each do |plugin| %> + + + + + + + <% end %> +
<%=h plugin.name %> + <%= 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? %> + <%= plugin.author_url.blank? ? h(plugin.author) : link_to(h(plugin.author), plugin.author_url) %><%=h plugin.version %><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %>
+<% else %> +

<%= l(:label_no_data) %>

+<% end %> diff --git a/app/views/admin/projects.html.erb b/app/views/admin/projects.html.erb new file mode 100644 index 000000000..2f520a236 --- /dev/null +++ b/app/views/admin/projects.html.erb @@ -0,0 +1,45 @@ +
+<%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %> +
+ +

<%=l(:label_project_plural)%>

+ +<%= form_tag({}, :method => :get) do %> +
<%= l(:label_filter_plural) %> + +<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + +<%= 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' %> +
+<% end %> +  + +
+ + + + + + + + +<% project_tree(@projects) do |project, level| %> + <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>"> + + + + + +<% end %> + +
<%=l(:label_project)%><%=l(:field_is_public)%><%=l(:field_created_on)%>
<%= link_to_project_settings(project, {}, :title => project.short_description) %><%= checked_image project.is_public? %><%= format_date(project.created_on) %> + <%= 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') %> +
+
+ +<% html_title(l(:label_project_plural)) -%> diff --git a/app/views/attachments/_form.html.erb b/app/views/attachments/_form.html.erb new file mode 100644 index 000000000..65ad8804a --- /dev/null +++ b/app/views/attachments/_form.html.erb @@ -0,0 +1,31 @@ + +<% if defined?(container) && container && container.saved_attachments %> + <% container.saved_attachments.each_with_index do |attachment, 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(' '.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}" %> + + <% end %> +<% end %> + + +<%= 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) %>) + + +<% content_for :header_tags do %> + <%= javascript_include_tag 'attachments' %> +<% end %> diff --git a/app/views/attachments/_links.html.erb b/app/views/attachments/_links.html.erb new file mode 100644 index 000000000..d2ab22ced --- /dev/null +++ b/app/views/attachments/_links.html.erb @@ -0,0 +1,33 @@ +
+<% for attachment in attachments %> +

<%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%> + <% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', :action => 'show', + :id => attachment, :filename => attachment.filename %> + <% end %> + <%= h(" - #{attachment.description}") unless attachment.description.blank? %> + (<%= number_to_human_size attachment.filesize %>) + <% if options[:deletable] %> + <%= link_to image_tag('delete.png'), attachment_path(attachment), + :data => {:confirm => l(:text_are_you_sure)}, + :method => :delete, + :class => 'delete', + :title => l(:button_delete) %> + <% end %> + <% if options[:author] %> + <%= h(attachment.author) %>, <%= format_time(attachment.created_on) %> + <% end %> +

+<% end %> +<% if defined?(thumbnails) && thumbnails %> + <% images = attachments.select(&:thumbnailable?) %> + <% if images.any? %> +
+ <% images.each do |attachment| %> +
<%= thumbnail_tag(attachment) %>
+ <% end %> +
+ <% end %> +<% end %> +
diff --git a/app/views/attachments/destroy.js.erb b/app/views/attachments/destroy.js.erb new file mode 100644 index 000000000..3cfb5845f --- /dev/null +++ b/app/views/attachments/destroy.js.erb @@ -0,0 +1 @@ +$('#attachments_<%= j params[:attachment_id] %>').remove(); diff --git a/app/views/attachments/diff.html.erb b/app/views/attachments/diff.html.erb new file mode 100644 index 000000000..8361bcb5e --- /dev/null +++ b/app/views/attachments/diff.html.erb @@ -0,0 +1,22 @@ +

<%=h @attachment.filename %>

+ +
+

<%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> + <%= link_to_user(@attachment.author) %>, <%= format_time(@attachment.created_on) %>

+

<%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> + (<%= number_to_human_size @attachment.filesize %>)

+
+<%= form_tag({}, :method => 'get') do %> +

+ <%= l(:label_view_diff) %>: + + +

+<% end %> +<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type, :diff_style => nil} %> + +<% html_title @attachment.filename %> + +<% content_for :header_tags do -%> + <%= stylesheet_link_tag "scm" -%> +<% end -%> diff --git a/app/views/attachments/file.html.erb b/app/views/attachments/file.html.erb new file mode 100644 index 000000000..57393b81e --- /dev/null +++ b/app/views/attachments/file.html.erb @@ -0,0 +1,17 @@ +

<%=h @attachment.filename %>

+ +
+

<%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> + <%= link_to_user(@attachment.author) %>, <%= format_time(@attachment.created_on) %>

+

<%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> + (<%= number_to_human_size @attachment.filesize %>)

+ +
+  +<%= render :partial => 'common/file', :locals => {:content => @content, :filename => @attachment.filename} %> + +<% html_title @attachment.filename %> + +<% content_for :header_tags do -%> + <%= stylesheet_link_tag "scm" -%> +<% end -%> diff --git a/app/views/attachments/show.api.rsb b/app/views/attachments/show.api.rsb new file mode 100644 index 000000000..5a9f74a91 --- /dev/null +++ b/app/views/attachments/show.api.rsb @@ -0,0 +1 @@ +render_api_attachment(@attachment, api) diff --git a/app/views/attachments/upload.api.rsb b/app/views/attachments/upload.api.rsb new file mode 100644 index 000000000..edd0b0af4 --- /dev/null +++ b/app/views/attachments/upload.api.rsb @@ -0,0 +1,3 @@ +api.upload do + api.token @attachment.token +end diff --git a/app/views/attachments/upload.js.erb b/app/views/attachments/upload.js.erb new file mode 100644 index 000000000..04e30b569 --- /dev/null +++ b/app/views/attachments/upload.js.erb @@ -0,0 +1,9 @@ +var fileSpan = $('#attachments_<%= j params[:attachment_id] %>'); +$('', { 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 --git a/app/views/auth_sources/_form.html.erb b/app/views/auth_sources/_form.html.erb new file mode 100644 index 000000000..05c6ca9e9 --- /dev/null +++ b/app/views/auth_sources/_form.html.erb @@ -0,0 +1,6 @@ +<%= error_messages_for 'auth_source' %> + +
+

<%= f.text_field :name, :required => true %>

+

<%= f.check_box :onthefly_register, :label => :field_onthefly %>

+
diff --git a/app/views/auth_sources/_form_auth_source_ldap.html.erb b/app/views/auth_sources/_form_auth_source_ldap.html.erb new file mode 100644 index 000000000..2ffd4d43e --- /dev/null +++ b/app/views/auth_sources/_form_auth_source_ldap.html.erb @@ -0,0 +1,24 @@ +<%= error_messages_for 'auth_source' %> + +
+

<%= f.text_field :name, :required => true %>

+

<%= f.text_field :host, :required => true %>

+

<%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS

+

<%= f.text_field :account %>

+

<%= 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]';" %>

+

<%= f.text_field :base_dn, :required => true, :size => 60 %>

+

<%= f.text_field :filter, :size => 60, :label => :field_auth_source_ldap_filter %>

+

<%= f.text_field :timeout, :size => 4 %>

+

<%= f.check_box :onthefly_register, :label => :field_onthefly %>

+
+ +
<%=l(:label_attribute_plural)%> +

<%= f.text_field :attr_login, :required => true, :size => 20 %>

+

<%= f.text_field :attr_firstname, :size => 20 %>

+

<%= f.text_field :attr_lastname, :size => 20 %>

+

<%= f.text_field :attr_mail, :size => 20 %>

+
diff --git a/app/views/auth_sources/edit.html.erb b/app/views/auth_sources/edit.html.erb new file mode 100644 index 000000000..fb43d3f91 --- /dev/null +++ b/app/views/auth_sources/edit.html.erb @@ -0,0 +1,6 @@ +

<%=l(:label_auth_source)%> (<%= h(@auth_source.auth_method_name) %>)

+ +<%= 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 --git a/app/views/auth_sources/index.html.erb b/app/views/auth_sources/index.html.erb new file mode 100644 index 000000000..ba1bd6296 --- /dev/null +++ b/app/views/auth_sources/index.html.erb @@ -0,0 +1,31 @@ +
+<%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %> +
+ +

<%=l(:label_auth_source_plural)%>

+ + + + + + + + + + +<% for source in @auth_sources %> + "> + + + + + + +<% end %> + +
<%=l(:field_name)%><%=l(:field_type)%><%=l(:field_host)%><%=l(:label_user_plural)%>
<%= link_to(h(source.name), :action => 'edit', :id => source)%><%= h source.auth_method_name %><%= h source.host %><%= h source.users.count %> + <%= link_to l(:button_test), try_connection_auth_source_path(source), :class => 'icon icon-test' %> + <%= delete_link auth_source_path(source) %> +
+ +

<%= pagination_links_full @auth_source_pages %>

diff --git a/app/views/auth_sources/new.html.erb b/app/views/auth_sources/new.html.erb new file mode 100644 index 000000000..3938b9104 --- /dev/null +++ b/app/views/auth_sources/new.html.erb @@ -0,0 +1,7 @@ +

<%=l(:label_auth_source_new)%> (<%= h(@auth_source.auth_method_name) %>)

+ +<%= 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 --git a/app/views/auto_completes/issues.html.erb b/app/views/auto_completes/issues.html.erb new file mode 100644 index 000000000..e292bbaeb --- /dev/null +++ b/app/views/auto_completes/issues.html.erb @@ -0,0 +1,7 @@ +<%= raw @issues.map {|issue| { + 'id' => issue.id, + 'label' => "#{issue.tracker} ##{issue.id}: #{truncate issue.subject.to_s, :length => 60}", + 'value' => issue.id + } + }.to_json +%> diff --git a/app/views/avatar/_avatar_form.html.erb b/app/views/avatar/_avatar_form.html.erb new file mode 100644 index 000000000..6e0df0387 --- /dev/null +++ b/app/views/avatar/_avatar_form.html.erb @@ -0,0 +1,27 @@ + + <%= image_tag(url_to_avatar(source), id: "avatar_image", size: AvatarHelper::AVATAR_SIZE)%> + + + + + +<%= file_field_tag 'avatar[image]', + :id => nil, + :class => 'file_selector', + :multiple => false, + :onchange => 'addInputAvatar(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 => upload_avatar_path(:format => 'js'), + :description_placeholder => nil ,# l(:label_optional_description) + :source_type => source.class.to_s, + :source_id => source.id.to_s + } %> +(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) + + +<% content_for :header_tags do %> + <%= javascript_include_tag 'avatars' %> +<% end %> diff --git a/app/views/avatar/upload.js.erb b/app/views/avatar/upload.js.erb new file mode 100644 index 000000000..a7a341f10 --- /dev/null +++ b/app/views/avatar/upload.js.erb @@ -0,0 +1,4 @@ +var imgSpan = $('#avatar_image'); + +imgSpan.attr({"src":'<%= @urlfile.to_s << "?" << Time.now.to_s%>'}); + diff --git a/app/views/bids/_history.html.erb b/app/views/bids/_history.html.erb new file mode 100644 index 000000000..4135208ac --- /dev/null +++ b/app/views/bids/_history.html.erb @@ -0,0 +1,37 @@ + + +<% if journals.size > 5 %> +<% unless state%> +
+<%= link_to l(:button_more), + {:controller => 'bids', :action => 'more', :bid_id => bid}, + :remote => true, + :method => 'get' %> +
+<% else %> +
+<%= link_to l(:button_back), + {:controller => 'bids', :action => 'back', :bid_id => bid}, + :remote => true, + :method => 'get' %> +
+<% end %> +<% end %> + +

<%=l(:label_user_response)%>(<%= journals.count%>)

+<% unless state%> + <% if journals.size > 5 %> + <% journals = journals[0, 5] %> + <% end %> +<% end %> +<% for journal in journals %> +
+
+

<%= link_to "##{journal.indice}", {}, :class => "journal-link" %> + <%= avatar(journal.user, :size => "24") %> + <%= l(:label_updated_time_by, :author => journal.user, :age => time_tag(journal.created_at)).html_safe%>

+ <%= render_notes(bid, journal, :reply_links => true) unless journal.notes.blank? %> +
+
+ <%= call_hook(:view_issues_history_journal_bottom, { :journal => journal }) %> +<% end %> diff --git a/app/views/bids/_new.html.erb b/app/views/bids/_new.html.erb new file mode 100644 index 000000000..1e3958148 --- /dev/null +++ b/app/views/bids/_new.html.erb @@ -0,0 +1,13 @@ +<%= form_tag({:controller => 'bids', + :action => 'create', + :bid_id => bid, + :sta => sta}, + :remote => true, + :method => :post) do %> + +

<%= label_tag 'user_message', l(:label_leave_message) %><%= text_area_tag 'user_message', nil %>

+

+ <%= submit_tag l(:button_leave_meassge), :name => nil %> + <%= submit_tag l(:button_clear), :name => nil, :onclick => "clearMessage('user_message');", :type => 'button' %> +

+<% end %> diff --git a/app/views/bids/_project_list.html.erb b/app/views/bids/_project_list.html.erb new file mode 100644 index 000000000..53eda2b0e --- /dev/null +++ b/app/views/bids/_project_list.html.erb @@ -0,0 +1,35 @@ +<% @bidding_project.each do |b_project|%> +
  • + + + + + + + +
    + + + + + + +
    + + + + + + + +
    <%= link_to(b_project.project.name, project_path(b_project.project)) %>
    <%= b_project.project.description %>
    + + + + + + + +
    应标人:<%= link_to(b_project.user.name, user_path(b_project.user)) %>
    应标宣言:<%= b_project.description %>
     
    +
  • +<% end %> diff --git a/app/views/bids/add.js.erb b/app/views/bids/add.js.erb new file mode 100644 index 000000000..9a6d1515a --- /dev/null +++ b/app/views/bids/add.js.erb @@ -0,0 +1,4 @@ +$('#bidding_project_list').html('<%= escape_javascript(render(:partial => 'project_list', :locals => {:bidding_project => @bidding_project})) %>'); +$("#project_id").val("请选择项目"); +$("#project_id").val("请输入应标ç†ç”±"); +$("#put-bid-form").hide(); \ No newline at end of file diff --git a/app/views/bids/back.js.erb b/app/views/bids/back.js.erb new file mode 100644 index 000000000..b2d3c5151 --- /dev/null +++ b/app/views/bids/back.js.erb @@ -0,0 +1 @@ +$('#history').html('<%= escape_javascript(render(:partial => 'history', :locals => {:bid => @bid, :journals => @jour, :state => @state})) %>'); diff --git a/app/views/bids/create.js.erb b/app/views/bids/create.js.erb new file mode 100644 index 000000000..a524d9dd8 --- /dev/null +++ b/app/views/bids/create.js.erb @@ -0,0 +1,2 @@ +$('#history').html('<%= escape_javascript(render(:partial => 'history', :locals => {:bid => @bid, :journals => @jour, :state => true})) %>'); +$('#user_message').val(""); diff --git a/app/views/bids/destroy.js.erb b/app/views/bids/destroy.js.erb new file mode 100644 index 000000000..c5e1516b0 --- /dev/null +++ b/app/views/bids/destroy.js.erb @@ -0,0 +1 @@ +$('#history').html('<%= escape_javascript(render(:partial => 'history', :locals => {:bid => @bid, :journals => @jour, :state => false})) %>'); diff --git a/app/views/bids/index.html.erb b/app/views/bids/index.html.erb new file mode 100644 index 000000000..74c0531f3 --- /dev/null +++ b/app/views/bids/index.html.erb @@ -0,0 +1,37 @@ +
    + <%= link_to("新建需求", {:controller => 'bids', :action => 'new_bid'}, :class => 'icon icon-add') %> +
    +

    需求列表

    + +
      + <% @bids.each do |bid|%> +
    • + + 悬èµï¼šï¿¥<%= bid.budget%> + <%= link_to bid.name, :controller => 'bids', :action => 'show', :bid_id => bid.id %> + <%= bid.author.name%> å‘布 39投标 +
    • + <% end %> + +
    • + + 悬èµï¼šï¿¥1000 + <%= link_to "宣传展示型网站开å‘_ä¼ä¸šç½‘站中英文", :controller => 'bids', :action => 'show', :bid_id => "2" %> + tellmey å‘布 24投标 +
    • + +
    • + + 悬èµï¼šï¿¥1000 + <%= link_to "移动应用终端无线支付åœè½¦åœºå¼€å‘", :controller => 'bids', :action => 'show', :bid_id => "3" %> + å¥¥ç¾Žç‰¹ç”µå­ å‘布 2投标 +
    • + +
    • + + 悬èµï¼šï¿¥1500 + <%= link_to "需è¦ä¸€ä¸ªå°åˆ·ç±»çš„erp系统", :controller => 'bids', :action => 'show', :bid_id => "4" %> + 海彩å°åˆ·æœ‰é™å…¬å¸ å‘布 17投标 +
    • + +
    \ No newline at end of file diff --git a/app/views/bids/more.js.erb b/app/views/bids/more.js.erb new file mode 100644 index 000000000..b2d3c5151 --- /dev/null +++ b/app/views/bids/more.js.erb @@ -0,0 +1 @@ +$('#history').html('<%= escape_javascript(render(:partial => 'history', :locals => {:bid => @bid, :journals => @jour, :state => @state})) %>'); diff --git a/app/views/bids/new.js.erb b/app/views/bids/new.js.erb new file mode 100644 index 000000000..d2cdeaae9 --- /dev/null +++ b/app/views/bids/new.js.erb @@ -0,0 +1,2 @@ +$('#user_message').val("<%= raw escape_javascript(@content) %>"); +showAndScrollTo("user_message", "user_message"); diff --git a/app/views/bids/new_bid.html.erb b/app/views/bids/new_bid.html.erb new file mode 100644 index 000000000..bfda90733 --- /dev/null +++ b/app/views/bids/new_bid.html.erb @@ -0,0 +1,14 @@ +
    +<%= form_tag({:controller => 'bids', + :action => 'index', + :remote => true, + :method => :post, + :id => 'new-bid-form'}) do %> +

    需求å称:<%= text_field_tag 'bid_title' %>

    +

    需求æè¿°ï¼š

    +

    <%= text_area_tag 'bid_description' %>

    +

    投资预算:<%= text_field_tag 'bid_budget' %>

    +

    投资时é™ï¼š<%= text_field_tag 'bid_deadline' %>

    + <%= submit_tag l(:button_submit) %> + <%end%> +
    diff --git a/app/views/bids/show.html.erb b/app/views/bids/show.html.erb new file mode 100644 index 000000000..a82711081 --- /dev/null +++ b/app/views/bids/show.html.erb @@ -0,0 +1,17 @@ +

    <%= link_to(@bid.author.name, user_path(@bid.author))%>:<%= @bid.name %>

    + + + + + + +

    需求æè¿°

    <%= @bid.description %>
    + +
    +<%= render :partial => 'history', :locals => { :bid => @bid, :journals => @jour, :state => false} %> +
    + +
    + <%= render :partial => 'new', :locals => {:bid => @bid, :sta => @state} %> +
    + diff --git a/app/views/bids/show_project.html.erb b/app/views/bids/show_project.html.erb new file mode 100644 index 000000000..c1af73b3b --- /dev/null +++ b/app/views/bids/show_project.html.erb @@ -0,0 +1,32 @@ +
    +
    +
    +<%= toggle_link "我è¦åº”æ ‡", 'put-bid-form', {:focus => 'project_id'} %> +
    + + +

    应标项目列表

    +
      +
      + <%= render :partial => 'project_list', :locals => {:bidding_project => @bidding_project} %> +
      +
    + diff --git a/app/views/boards/_form.html.erb b/app/views/boards/_form.html.erb new file mode 100644 index 000000000..daaecee53 --- /dev/null +++ b/app/views/boards/_form.html.erb @@ -0,0 +1,9 @@ +<%= error_messages_for @board %> + +
    +

    <%= f.text_field :name, :required => true %>

    +

    <%= f.text_field :description, :required => true, :size => 80 %>

    +<% if @board.valid_parents.any? %> +

    <%= f.select :parent_id, boards_options_for_select(@board.valid_parents), :include_blank => true, :label => :field_board_parent %>

    +<% end %> +
    diff --git a/app/views/boards/edit.html.erb b/app/views/boards/edit.html.erb new file mode 100644 index 000000000..21730e96e --- /dev/null +++ b/app/views/boards/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_board) %>

    + +<%= labelled_form_for @board, :url => project_board_path(@project, @board) do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/boards/index.html.erb b/app/views/boards/index.html.erb new file mode 100644 index 000000000..71aba48bb --- /dev/null +++ b/app/views/boards/index.html.erb @@ -0,0 +1,38 @@ +

    <%= l(:label_board_plural) %>

    + + + + + + + + + +<% Board.board_tree(@boards) do |board, level| %> + + + + + + +<% end %> + +
    <%= l(:label_board) %><%= l(:label_topic_plural) %><%= l(:label_message_plural) %><%= l(:label_message_last) %>
    + <%= link_to h(board.name), project_board_path(board.project, board), :class => "board" %>
    + <%=h board.description %> +
    <%= board.topics_count %><%= board.messages_count %> + <% if board.last_message %> + <%= authoring board.last_message.created_on, board.last_message.author %>
    + <%= link_to_message board.last_message %> + <% end %> +
    + +<% 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 --git a/app/views/boards/new.html.erb b/app/views/boards/new.html.erb new file mode 100644 index 000000000..509910ca5 --- /dev/null +++ b/app/views/boards/new.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_board_new) %>

    + +<%= labelled_form_for @board, :url => project_boards_path(@project) do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/boards/show.html.erb b/app/views/boards/show.html.erb new file mode 100644 index 000000000..bababcc3f --- /dev/null +++ b/app/views/boards/show.html.erb @@ -0,0 +1,66 @@ +<%= board_breadcrumb(@board) %> + +
    +<%= 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) %> +
    + + + +

    <%=h @board.name %>

    +

    <%=h @board.description %>

    + +<% if @topics.any? %> + + + + + <%= 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)) %> + + + <% @topics.each do |topic| %> + + + + + + + + <% end %> + +
    <%= l(:field_subject) %><%= l(:field_author) %>
    <%= link_to h(topic.subject), board_message_path(@board, topic) %><%= link_to_user(topic.author) %><%= format_time(topic.created_on) %><%= topic.replies_count %> + <% if topic.last_reply %> + <%= authoring topic.last_reply.created_on, topic.last_reply.author %>
    + <%= link_to_message topic.last_reply %> + <% end %> +
    +

    <%= pagination_links_full @topic_pages, @topic_count %>

    +<% else %> +

    <%= l(:label_no_data) %>

    +<% 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 --git a/app/views/calendars/show.html.erb b/app/views/calendars/show.html.erb new file mode 100644 index 000000000..9166974fa --- /dev/null +++ b/app/views/calendars/show.html.erb @@ -0,0 +1,43 @@ +

    <%= @query.new_record? ? l(:label_calendar) : h(@query.name) %>

    + +<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, + :method => :get, :id => 'query_form') do %> +<%= hidden_field_tag 'set_filter', '1' %> +
    "> + <%= l(:label_filter_plural) %> +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    + +

    + <%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %> +

    + +

    +<%= 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' %> +

    +<% end %> + +<%= error_messages_for 'query' %> +<% if @query.valid? %> +<%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %> + +

    + <%= l(:text_tip_issue_begin_day) %> + <%= l(:text_tip_issue_end_day) %> + <%= l(:text_tip_issue_begin_end_day) %> +

    +<% end %> + +<% content_for :sidebar do %> + <%= render :partial => 'issues/sidebar' %> +<% end %> + +<% html_title(l(:label_calendar)) -%> diff --git a/app/views/common/_calendar.html.erb b/app/views/common/_calendar.html.erb new file mode 100644 index 000000000..7951b68ce --- /dev/null +++ b/app/views/common/_calendar.html.erb @@ -0,0 +1,32 @@ + + +<% 7.times do |i| %><% end %> + + + +<% day = calendar.startdt +while day <= calendar.enddt %> +<%= ("".html_safe) if day.cwday == calendar.first_wday %> + +<%= ''.html_safe if day.cwday==calendar.last_wday and day!=calendar.enddt %> +<% day = day + 1 +end %> + + +
    <%= day_name( (calendar.first_wday+i)%7 ) %>
    #{(day+(11-day.cwday)%7).cweek} +

    <%= day.day %>

    +<% calendar.events_on(day).each do |i| %> + <% if i.is_a? Issue %> +
    + <%= h("#{i.project} -") unless @project && @project == i.project %> + <%= link_to_issue i, :truncate => 30 %> + <%= render_issue_tooltip i %> +
    + <% else %> + + <%= h("#{i.project} -") unless @project && @project == i.project %> + <%= link_to_version i%> + + <% end %> +<% end %> +
    diff --git a/app/views/common/_diff.html.erb b/app/views/common/_diff.html.erb new file mode 100644 index 000000000..0d30bedd2 --- /dev/null +++ b/app/views/common/_diff.html.erb @@ -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| -%> +
    +<% if diff.diff_type == 'sbs' -%> + + + + + + + +<% table_file.each_line do |spacing, line| -%> +<% if spacing -%> + + + +<% end -%> + + + + + + +<% end -%> + +
    + <%= table_file.file_name %> +
    ......
    <%= line.nb_line_left %> +
    <%= line.html_line_left.html_safe %>
    +
    <%= line.nb_line_right %> +
    <%= line.html_line_right.html_safe %>
    +
    + +<% else -%> + + + + + + + +<% table_file.each_line do |spacing, line| %> +<% if spacing -%> + + + +<% end -%> + + + + + +<% end -%> + +
    + <%= table_file.file_name %> +
    ......
    <%= line.nb_line_left %><%= line.nb_line_right %> +
    <%= line.html_line.html_safe %>
    +
    +<% end -%> +
    +<% end -%> + +<%= l(:text_diff_truncated) if diff.truncated? %> diff --git a/app/views/common/_file.html.erb b/app/views/common/_file.html.erb new file mode 100644 index 000000000..22126b949 --- /dev/null +++ b/app/views/common/_file.html.erb @@ -0,0 +1,18 @@ +
    + + +<% line_num = 1 %> +<% syntax_highlight_lines(filename, Redmine::CodesetUtil.to_utf8_by_setting(content)).each do |line| %> + + + + + <% line_num += 1 %> +<% end %> + +
    + <%= line_num %> + +
    <%= line.html_safe %>
    +
    +
    diff --git a/app/views/common/_preview.html.erb b/app/views/common/_preview.html.erb new file mode 100644 index 000000000..90d83ce8c --- /dev/null +++ b/app/views/common/_preview.html.erb @@ -0,0 +1,3 @@ +
    <%= l(:label_preview) %> +<%= textilizable @text, :attachments => @attachments, :object => @previewed %> +
    diff --git a/app/views/common/_project.html.erb b/app/views/common/_project.html.erb new file mode 100644 index 000000000..516ed0f5e --- /dev/null +++ b/app/views/common/_project.html.erb @@ -0,0 +1,58 @@ +
    +
    + <%= content_tag('div', tag('img', {:src => '../images/logo-only_med.png', :class => 'img_ta'}, false, false), :class => 'img-tag') %> +
    +
    +

    + Claimed by <%= content_tag('a', project.name) %> | Analyzed about 11 hours ago +

    +

    + <%= textilizable(project.short_description, :project => project) %> +

    +
    +
    +

    + <%= content_tag('a', "9.23M") %><%= content_tag('span', "lines of codes") %> +

    +

    + <%= content_tag('a', "963") %><%= content_tag('span', "current contributors") %> +

    +

    + <%= content_tag('a', "1 day") %><%= content_tag('span', "since last commits") %> +

    +

    + <%= content_tag('a', "12,169") %><%= content_tag('span', "users on trustie2") %> +

    +
    +
    + <%= content_tag('a', tag('img', {:src => '../images/pai.png', :class => 'img-ta'}, false, false), :class => 'img-tag3') %> + <%= content_tag('div', "Vert High Activity", :class => 'img-tag4') %> + <%= content_tag('div', tag('img', {:src => '../images/stars_ro.png', :class => 'img-ta'}, false, false), :class => 'img-tag2') %> + <%= content_tag('div', "#{WatchersOfProjects.watcher_count(project)}Reviews", :class => 'img-tag1') %> +
    +
    +
    +
    + <%= content_tag('a', 'Mostly written in C++') %> +
    +
    + <%= content_tag('a', 'Licenses:') %><%= content_tag('span', 'GPL-2.0+, LGPL, MPL-1.1') %> +
    +
    +
    + <%= tag('img', {:src => "../images/user.png"}, false, false) %> + <% tags = ProjectTags.find_tag(project.id) + tags.each do |t_tag| + content = t_tag.tag.content + description = t_tag.description -%> + <%= content_tag('a', content, :class => 'tag', :title => description) %> + <% end -%> + <%= content_tag('a', 'css', :class => 'tag') %> + <%= content_tag('a', 'web_browser', :class => 'tag') %> + <%= content_tag('a', 'development', :class => 'tag') %> + <%= content_tag('a', 'client', :class => 'tag') %> + <%= content_tag('a', 'web', :class => 'tag') %> + <%= content_tag('a', 'xhtml', :class => 'tag') %> + <%= content_tag('a', 'tabbed', :class => 'tag') %> + <%= content_tag('a', 'and more') %> +
    diff --git a/app/views/common/_tabs.html.erb b/app/views/common/_tabs.html.erb new file mode 100644 index 000000000..2cf90135f --- /dev/null +++ b/app/views/common/_tabs.html.erb @@ -0,0 +1,28 @@ +<% selected_tab = params[:tab] ? params[:tab].to_s : tabs.first[:name] %> + +
    +
      + <% tabs.each do |tab| -%> +
    • <%= 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;" %>
    • + <% end -%> +
    + +
    + + + +<% 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 --git a/app/views/common/error.html.erb b/app/views/common/error.html.erb new file mode 100644 index 000000000..20a524bd9 --- /dev/null +++ b/app/views/common/error.html.erb @@ -0,0 +1,8 @@ +

    <%=h @status %>

    + +<% if @message.present? %> +

    <%=h @message %>

    +<% end %> +

    <%= l(:button_back) %>

    + +<% html_title @status %> diff --git a/app/views/common/error_messages.api.rsb b/app/views/common/error_messages.api.rsb new file mode 100644 index 000000000..811d2a863 --- /dev/null +++ b/app/views/common/error_messages.api.rsb @@ -0,0 +1,5 @@ +api.array :errors do + @error_messages.each do |message| + api.error message + end +end diff --git a/app/views/common/feed.atom.builder b/app/views/common/feed.atom.builder new file mode 100644 index 000000000..70dacc75a --- /dev/null +++ b/app/views/common/feed.atom.builder @@ -0,0 +1,31 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do + xml.title truncate_single_line(@title, :length => 100) + xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false)) + xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil)) + xml.id url_for(:controller => 'welcome', :only_path => false) + xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema) + xml.author { xml.name "#{Setting.app_title}" } + xml.generator(:uri => Redmine::Info.url) { xml.text! Redmine::Info.app_name; } + @items.each do |item| + xml.entry do + url = url_for(item.event_url(:only_path => false)) + if @project + xml.title truncate_single_line(item.event_title, :length => 100) + else + xml.title truncate_single_line("#{item.project} - #{item.event_title}", :length => 100) + end + xml.link "rel" => "alternate", "href" => url + xml.id url + xml.updated item.event_datetime.xmlschema + author = item.event_author if item.respond_to?(:event_author) + xml.author do + xml.name(author) + xml.email(author.mail) if author.is_a?(User) && !author.mail.blank? && !author.pref.hide_mail + end if author + xml.content "type" => "html" do + xml.text! textilizable(item, :event_description, :only_path => false) + end + end + end +end diff --git a/app/views/context_menus/issues.html.erb b/app/views/context_menus/issues.html.erb new file mode 100644 index 000000000..b30c3a81f --- /dev/null +++ b/app/views/context_menus/issues.html.erb @@ -0,0 +1,139 @@ +
      + <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %> + + <% if @issue -%> +
    • <%= context_menu_link l(:button_edit), edit_issue_path(@issue), + :class => 'icon-edit', :disabled => !@can[:edit] %>
    • + <% else %> +
    • <%= context_menu_link l(:button_edit), bulk_edit_issues_path(:ids => @issue_ids), + :class => 'icon-edit', :disabled => !@can[:edit] %>
    • + <% end %> + + <% if @allowed_statuses.present? %> +
    • + <%= l(:field_status) %> +
        + <% @allowed_statuses.each do |s| -%> +
      • <%= 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] %>
      • + <% end -%> +
      +
    • + <% end %> + + <% if @trackers.present? %> +
    • + <%= l(:field_tracker) %> +
        + <% @trackers.each do |t| -%> +
      • <%= 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] %>
      • + <% end -%> +
      +
    • + <% end %> + + <% if @safe_attributes.include?('priority_id') && @priorities.present? -%> +
    • + <%= l(:field_priority) %> +
        + <% @priorities.each do |p| -%> +
      • <%= 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?}) %>
      • + <% end -%> +
      +
    • + <% end %> + + <% if @safe_attributes.include?('fixed_version_id') && @versions.present? -%> +
    • + <%= l(:field_fixed_version) %> +
        + <% @versions.sort.each do |v| -%> +
      • <%= 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] %>
      • + <% end -%> +
      • <%= 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] %>
      • +
      +
    • + <% end %> + + <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%> +
    • + <%= l(:field_assigned_to) %> +
        + <% if @assignables.include?(User.current) %> +
      • <%= 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] %>
      • + <% end %> + <% @assignables.each do |u| -%> +
      • <%= 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] %>
      • + <% end -%> +
      • <%= 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] %>
      • +
      +
    • + <% end %> + + <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%> +
    • + <%= l(:field_category) %> +
        + <% @project.issue_categories.each do |u| -%> +
      • <%= 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] %>
      • + <% end -%> +
      • <%= 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] %>
      • +
      +
    • + <% end -%> + + <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %> +
    • + <%= l(:field_done_ratio) %> +
        + <% (0..10).map{|x|x*10}.each do |p| -%> +
      • <%= 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?}) %>
      • + <% end -%> +
      +
    • + <% end %> + + <% @options_by_custom_field.each do |field, options| %> +
    • + <%= h(field.name) %> +
        + <% options.each do |text, value| %> +
      • <%= bulk_update_custom_field_context_menu_link(field, text, value || text) %>
      • + <% end %> + <% unless field.is_required? %> +
      • <%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '__none__') %>
      • + <% end %> +
      +
    • + <% end %> + +<% if User.current.logged? %> +
    • <%= watcher_link(@issues, User.current) %>
    • +<% end %> + +<% if @issue.present? %> + <% if @can[:log_time] -%> +
    • <%= context_menu_link l(:button_log_time), new_issue_time_entry_path(@issue), + :class => 'icon-time-add' %>
    • + <% end %> +
    • <%= context_menu_link l(:button_copy), project_copy_issue_path(@project, @issue), + :class => 'icon-copy', :disabled => !@can[:copy] %>
    • +<% else %> +
    • <%= context_menu_link l(:button_copy), bulk_edit_issues_path(:ids => @issue_ids, :copy => '1'), + :class => 'icon-copy', :disabled => !@can[:move] %>
    • +<% end %> +
    • <%= 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] %>
    • + + <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %> +
    diff --git a/app/views/context_menus/time_entries.html.erb b/app/views/context_menus/time_entries.html.erb new file mode 100644 index 000000000..10dbcafd2 --- /dev/null +++ b/app/views/context_menus/time_entries.html.erb @@ -0,0 +1,33 @@ +
      + <% if !@time_entry.nil? -%> +
    • <%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => @time_entry}, + :class => 'icon-edit', :disabled => !@can[:edit] %>
    • + <% else %> +
    • <%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id)}, + :class => 'icon-edit', :disabled => !@can[:edit] %>
    • + <% end %> + + <%= call_hook(:view_time_entries_context_menu_start, {:time_entries => @time_entries, :can => @can, :back => @back }) %> + + <% if @activities.present? -%> +
    • + <%= l(:field_activity) %> +
        + <% @activities.each do |u| -%> +
      • <%= context_menu_link h(u.name), {:controller => 'timelog', :action => 'bulk_update', :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] %>
      • + <% end -%> +
      • <%= context_menu_link l(:label_none), {:controller => 'timelog', :action => 'bulk_update', :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] %>
      • +
      +
    • + <% end %> + + <%= call_hook(:view_time_entries_context_menu_end, {:time_entries => @time_entries, :can => @can, :back => @back }) %> + +
    • + <%= context_menu_link l(:button_delete), + {:controller => 'timelog', :action => 'destroy', :ids => @time_entries.collect(&:id), :back_url => @back}, + :method => :delete, :data => {:confirm => l(:text_time_entries_destroy_confirmation)}, :class => 'icon-del', :disabled => !@can[:delete] %> +
    • +
    diff --git a/app/views/custom_fields/_form.html.erb b/app/views/custom_fields/_form.html.erb new file mode 100644 index 000000000..b6f7ddb1d --- /dev/null +++ b/app/views/custom_fields/_form.html.erb @@ -0,0 +1,99 @@ +<%= error_messages_for 'custom_field' %> + +
    +

    <%= f.text_field :name, :required => true %>

    +

    <%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %>

    + +<% if @custom_field.format_in? 'list', 'user', 'version' %> +

    + <%= f.check_box :multiple %> + <% if !@custom_field.new_record? && @custom_field.multiple %> + <%= l(:text_turning_multiple_off) %> + <% end %> +

    +<% end %> + +<% unless @custom_field.format_in? 'list', 'bool', 'date', 'user', 'version' %> +

    + <%= f.text_field :min_length, :size => 5, :no_label => true %> - + <%= f.text_field :max_length, :size => 5, :no_label => true %>
    (<%=l(:text_min_max_length_info)%>)

    +

    <%= f.text_field :regexp, :size => 50 %>
    (<%=l(:text_regexp_info)%>)

    +<% end %> + +<% if @custom_field.format_in? 'list' %> +

    + <%= f.text_area :possible_values, :value => @custom_field.possible_values.to_a.join("\n"), :rows => 15 %> + <%= l(:text_custom_field_possible_values_info) %> +

    +<% end %> + +<% case @custom_field.field_format %> +<% when 'bool' %> +

    <%= f.check_box(:default_value) %>

    +<% when 'text' %> +

    <%= f.text_area(:default_value, :rows => 8) %>

    +<% when 'date' %> +

    <%= f.text_field(:default_value, :size => 10) %>

    + <%= calendar_for('custom_field_default_value') %> +<% when 'user', 'version' %> +<% else %> +

    <%= f.text_field(:default_value) %>

    +<% end %> + +<%= call_hook(:view_custom_fields_form_upper_box, :custom_field => @custom_field, :form => f) %> +
    + +
    +<% case @custom_field.class.name +when "IssueCustomField" %> + +
    <%=l(:label_tracker_plural)%> + <% 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}" %> + + <% end %> + <%= hidden_field_tag "custom_field[tracker_ids][]", '' %> +
    +   +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :is_for_all %>

    +

    <%= f.check_box :is_filter %>

    +

    <%= f.check_box :searchable %>

    + +<% when "UserCustomField" %> +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :visible %>

    +

    <%= f.check_box :editable %>

    +

    <%= f.check_box :is_filter %>

    + +<% when "ProjectCustomField" %> +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :visible %>

    +

    <%= f.check_box :searchable %>

    +

    <%= f.check_box :is_filter %>

    + +<% when "VersionCustomField" %> +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :is_filter %>

    + +<% when "GroupCustomField" %> +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :is_filter %>

    + +<% when "TimeEntryCustomField" %> +

    <%= f.check_box :is_required %>

    +

    <%= f.check_box :is_filter %>

    + +<% else %> +

    <%= f.check_box :is_required %>

    + +<% end %> +<%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %> +
    + +<% include_calendar_headers_tags %> diff --git a/app/views/custom_fields/_index.html.erb b/app/views/custom_fields/_index.html.erb new file mode 100644 index 000000000..79fc09ae5 --- /dev/null +++ b/app/views/custom_fields/_index.html.erb @@ -0,0 +1,32 @@ + + + + + + <% if tab[:name] == 'IssueCustomField' %> + + + <% end %> + + + + + <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%> + "> + + + + <% if tab[:name] == 'IssueCustomField' %> + + + <% end %> + + + + <% end; reset_cycle %> + +
    <%=l(:field_name)%><%=l(:field_field_format)%><%=l(:field_is_required)%><%=l(:field_is_for_all)%><%=l(:label_used_by)%><%=l(:button_sort)%>
    <%= link_to h(custom_field.name), edit_custom_field_path(custom_field) %><%= l(Redmine::CustomFieldFormat.label_for(custom_field.field_format)) %><%= checked_image custom_field.is_required? %><%= checked_image custom_field.is_for_all? %><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %><%= reorder_links('custom_field', {:action => 'update', :id => custom_field}, :put) %> + <%= delete_link custom_field_path(custom_field) %> +
    + +

    <%= link_to l(:label_custom_field_new), new_custom_field_path(:type => tab[:name]), :class => 'icon icon-add' %>

    diff --git a/app/views/custom_fields/edit.html.erb b/app/views/custom_fields/edit.html.erb new file mode 100644 index 000000000..7f62c0375 --- /dev/null +++ b/app/views/custom_fields/edit.html.erb @@ -0,0 +1,8 @@ +

    <%= link_to l(:label_custom_field_plural), :controller => 'custom_fields', :action => 'index' %> + » <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %> + » <%=h @custom_field.name %>

    + +<%= labelled_form_for :custom_field, @custom_field, :url => custom_field_path(@custom_field), :html => {:method => :put, :id => 'custom_field_form'} do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/custom_fields/index.html.erb b/app/views/custom_fields/index.html.erb new file mode 100644 index 000000000..fd43ea82f --- /dev/null +++ b/app/views/custom_fields/index.html.erb @@ -0,0 +1,5 @@ +

    <%=l(:label_custom_field_plural)%>

    + +<%= render_tabs custom_fields_tabs %> + +<% html_title(l(:label_custom_field_plural)) -%> diff --git a/app/views/custom_fields/new.html.erb b/app/views/custom_fields/new.html.erb new file mode 100644 index 000000000..a0c8ac083 --- /dev/null +++ b/app/views/custom_fields/new.html.erb @@ -0,0 +1,19 @@ +

    <%= link_to l(:label_custom_field_plural), :controller => 'custom_fields', :action => 'index' %> + » <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %> + » <%= l(:label_custom_field_new) %>

    + +<%= labelled_form_for :custom_field, @custom_field, :url => custom_fields_path, :html => {:id => 'custom_field_form'} do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= hidden_field_tag 'type', @custom_field.type %> +<%= submit_tag l(:button_save) %> +<% end %> + +<%= javascript_tag do %> +$('#custom_field_field_format').change(function(){ + $.ajax({ + url: '<%= new_custom_field_path(:format => 'js') %>', + type: 'get', + data: $('#custom_field_form').serialize() + }); +}); +<% end %> diff --git a/app/views/custom_fields/new.js.erb b/app/views/custom_fields/new.js.erb new file mode 100644 index 000000000..d77c97f07 --- /dev/null +++ b/app/views/custom_fields/new.js.erb @@ -0,0 +1 @@ +$('#content').html('<%= escape_javascript(render :template => 'custom_fields/new', :layout => nil, :formats => [:html]) %>') diff --git a/app/views/documents/_document.html.erb b/app/views/documents/_document.html.erb new file mode 100644 index 000000000..e14d880a7 --- /dev/null +++ b/app/views/documents/_document.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to h(document.title), document_path(document) %>

    +

    <%= format_time(document.updated_on) %>

    + +
    + <%= textilizable(truncate_lines(document.description), :object => document) %> +
    diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb new file mode 100644 index 000000000..53d8fc3bb --- /dev/null +++ b/app/views/documents/_form.html.erb @@ -0,0 +1,15 @@ +<%= error_messages_for @document %> + +
    +

    <%= f.select :category_id, DocumentCategory.active.collect {|c| [c.name, c.id]} %>

    +

    <%= f.text_field :title, :required => true, :size => 60 %>

    +

    <%= f.text_area :description, :cols => 60, :rows => 15, :class => 'wiki-edit' %>

    +
    + +<%= wikitoolbar_for 'document_description' %> + +<% if @document.new_record? %> +
    +

    <%= render :partial => 'attachments/form', :locals => {:container => @document} %>

    +
    +<% end %> diff --git a/app/views/documents/edit.html.erb b/app/views/documents/edit.html.erb new file mode 100644 index 000000000..8a6122f8c --- /dev/null +++ b/app/views/documents/edit.html.erb @@ -0,0 +1,8 @@ +

    <%=l(:label_document)%>

    + +<%= labelled_form_for @document do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> +

    <%= submit_tag l(:button_save) %>

    +<% end %> + + diff --git a/app/views/documents/index.html.erb b/app/views/documents/index.html.erb new file mode 100644 index 000000000..28b524567 --- /dev/null +++ b/app/views/documents/index.html.erb @@ -0,0 +1,34 @@ +
    +<%= 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) %> +
    + + + +

    <%=l(:label_document_plural)%>

    + +<% if @grouped.empty? %>

    <%= l(:label_no_data) %>

    <% end %> + +<% @grouped.keys.sort.each do |group| %> +

    <%= group %>

    + <%= render :partial => 'documents/document', :collection => @grouped[group] %> +<% end %> + +<% content_for :sidebar do %> +

    <%= l(:label_sort_by, '') %>

    + <%= link_to l(:field_category), {:sort_by => 'category'}, :class => (@sort_by == 'category' ? 'selected' :nil) %>
    + <%= link_to l(:label_date), {:sort_by => 'date'}, :class => (@sort_by == 'date' ? 'selected' :nil) %>
    + <%= link_to l(:field_title), {:sort_by => 'title'}, :class => (@sort_by == 'title' ? 'selected' :nil) %>
    + <%= link_to l(:field_author), {:sort_by => 'author'}, :class => (@sort_by == 'author' ? 'selected' :nil) %> +<% end %> + +<% html_title(l(:label_document_plural)) -%> diff --git a/app/views/documents/new.html.erb b/app/views/documents/new.html.erb new file mode 100644 index 000000000..e90bf7e27 --- /dev/null +++ b/app/views/documents/new.html.erb @@ -0,0 +1,6 @@ +

    <%=l(:label_document_new)%>

    + +<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> +

    <%= submit_tag l(:button_create) %>

    +<% end %> diff --git a/app/views/documents/show.html.erb b/app/views/documents/show.html.erb new file mode 100644 index 000000000..99bcc2a08 --- /dev/null +++ b/app/views/documents/show.html.erb @@ -0,0 +1,32 @@ +
    +<% 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 %> +
    + +

    <%=h @document.title %>

    + +

    <%=h @document.category.name %>
    +<%= format_date @document.created_on %>

    +
    +<%= textilizable @document.description, :attachments => @document.attachments %> +
    + +

    <%= l(:label_attachment_plural) %>

    +<%= link_to_attachments @document %> + +<% if authorize_for('documents', 'add_attachment') %> +

    <%= link_to l(:label_attachment_new), {}, :onclick => "$('#add_attachment_form').show(); return false;", + :id => 'attach_files_link' %>

    + <%= form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %> +
    +

    <%= render :partial => 'attachments/form' %>

    +
    + <%= submit_tag l(:button_add) %> + <% end %> +<% end %> + +<% html_title @document.title -%> diff --git a/app/views/enumerations/_form.html.erb b/app/views/enumerations/_form.html.erb new file mode 100644 index 000000000..8ff774d9d --- /dev/null +++ b/app/views/enumerations/_form.html.erb @@ -0,0 +1,11 @@ +<%= error_messages_for 'enumeration' %> + +
    +

    <%= f.text_field :name %>

    +

    <%= f.check_box :active %>

    +

    <%= f.check_box :is_default %>

    + + <% @enumeration.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :enumeration, value %>

    + <% end %> +
    diff --git a/app/views/enumerations/destroy.html.erb b/app/views/enumerations/destroy.html.erb new file mode 100644 index 000000000..3c595e032 --- /dev/null +++ b/app/views/enumerations/destroy.html.erb @@ -0,0 +1,12 @@ +

    <%= l(@enumeration.option_name) %>: <%=h @enumeration %>

    + +<%= form_tag({}, :method => :delete) do %> +
    +

    <%= l(:text_enumeration_destroy_question, @enumeration.objects_count) %>

    +

    +<%= select_tag 'reassign_to_id', (content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---") + options_from_collection_for_select(@enumerations, 'id', 'name')) %>

    +
    + +<%= submit_tag l(:button_apply) %> +<%= link_to l(:button_cancel), enumerations_path %> +<% end %> diff --git a/app/views/enumerations/edit.html.erb b/app/views/enumerations/edit.html.erb new file mode 100644 index 000000000..c3c0b895f --- /dev/null +++ b/app/views/enumerations/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to l(@enumeration.option_name), enumerations_path %> » <%=h @enumeration %>

    + +<%= labelled_form_for :enumeration, @enumeration, :url => enumeration_path(@enumeration), :html => {:method => :put} do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/enumerations/index.api.rsb b/app/views/enumerations/index.api.rsb new file mode 100644 index 000000000..2fc70b987 --- /dev/null +++ b/app/views/enumerations/index.api.rsb @@ -0,0 +1,9 @@ +api.array @klass.name.underscore.pluralize do + @enumerations.each do |enumeration| + api.__send__ @klass.name.underscore do + api.id enumeration.id + api.name enumeration.name + api.is_default enumeration.is_default + end + end +end diff --git a/app/views/enumerations/index.html.erb b/app/views/enumerations/index.html.erb new file mode 100644 index 000000000..fe7634bf3 --- /dev/null +++ b/app/views/enumerations/index.html.erb @@ -0,0 +1,34 @@ +

    <%=l(:label_enumerations)%>

    + +<% Enumeration.get_subclasses.each do |klass| %> +

    <%= l(klass::OptionName) %>

    + +<% enumerations = klass.shared %> +<% if enumerations.any? %> + + + + + + + + +<% enumerations.each do |enumeration| %> + + + + + + + +<% end %> +
    <%= l(:field_name) %><%= l(:field_is_default) %><%= l(:field_active) %>
    <%= link_to h(enumeration), edit_enumeration_path(enumeration) %><%= checked_image enumeration.is_default? %><%= checked_image enumeration.active? %><%= reorder_links('enumeration', {:action => 'update', :id => enumeration}, :put) %> + <%= delete_link enumeration_path(enumeration) %> +
    +<% reset_cycle %> +<% end %> + +

    <%= link_to l(:label_enumeration_new), new_enumeration_path(:type => klass.name) %>

    +<% end %> + +<% html_title(l(:label_enumerations)) -%> diff --git a/app/views/enumerations/new.html.erb b/app/views/enumerations/new.html.erb new file mode 100644 index 000000000..216b49298 --- /dev/null +++ b/app/views/enumerations/new.html.erb @@ -0,0 +1,7 @@ +

    <%= link_to l(@enumeration.option_name), enumerations_path %> » <%=l(:label_enumeration_new)%>

    + +<%= labelled_form_for :enumeration, @enumeration, :url => enumerations_path do |f| %> + <%= f.hidden_field :type %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/files/index.html.erb b/app/views/files/index.html.erb new file mode 100644 index 000000000..e83ddc879 --- /dev/null +++ b/app/views/files/index.html.erb @@ -0,0 +1,46 @@ +
    +<%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %> +
    + +

    <%=l(:label_attachment_plural)%>

    + +<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %> + + + + <%= 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') %> + + + + +<% @containers.each do |container| %> + <% next if container.attachments.empty? -%> + <% if container.is_a?(Version) -%> + + + + <% end -%> + <% container.attachments.each do |file| %> + "> + + + + + + + + <% end + reset_cycle %> +<% end %> + +
    MD5
    + <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %> +
    <%= link_to_attachment file, :download => true, :title => file.description %><%= format_time(file.created_on) %><%= number_to_human_size(file.filesize) %><%= file.downloads %><%= file.digest %> + <%= link_to(image_tag('delete.png'), attachment_path(file), + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %> +
    + +<% html_title(l(:label_attachment_plural)) -%> diff --git a/app/views/files/new.html.erb b/app/views/files/new.html.erb new file mode 100644 index 000000000..2558d8b12 --- /dev/null +++ b/app/views/files/new.html.erb @@ -0,0 +1,16 @@ +

    <%=l(:label_attachment_new)%>

    + +<%= error_messages_for 'attachment' %> +<%= form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %> +
    + +<% if @versions.any? %> +

    +<%= select_tag "version_id", content_tag('option', '') + + options_from_collection_for_select(@versions, "id", "name") %>

    +<% end %> + +

    <%= render :partial => 'attachments/form' %>

    +
    +<%= submit_tag l(:button_add) %> +<% end %> diff --git a/app/views/gantts/show.html.erb b/app/views/gantts/show.html.erb new file mode 100644 index 000000000..6ec189256 --- /dev/null +++ b/app/views/gantts/show.html.erb @@ -0,0 +1,319 @@ +<% @gantt.view = self %> +

    <%= @query.new_record? ? l(:label_gantt) : h(@query.name) %>

    + +<%= 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' %> +
    "> + <%= l(:label_filter_plural) %> +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    + + +

    + <%= gantt_zoom_link(@gantt, :in) %> + <%= gantt_zoom_link(@gantt, :out) %> +

    + +

    +<%= 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' %> +

    +<% 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 %> +

    <%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %>

    +<% end %> + + + + + + + +
    + <% + 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 %> + +
    +<% + style = "" + style += "width: #{g_width - 1}px;" + style += "height: #{headers_height}px;" + style += 'background: #eee;' +%> +<%= content_tag(:div, ' '.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, ' '.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, ' '.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") %> +
    +
    + + + + + + +
    + <%= link_to_content_update("\xc2\xab " + l(:label_previous), + params.merge(@gantt.params_previous)) %> + + <%= link_to_content_update(l(:label_next) + " \xc2\xbb", + params.merge(@gantt.params_next)) %> +
    + +<% 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 --git a/app/views/groups/_form.html.erb b/app/views/groups/_form.html.erb new file mode 100644 index 000000000..7dc224061 --- /dev/null +++ b/app/views/groups/_form.html.erb @@ -0,0 +1,8 @@ +<%= error_messages_for @group %> + +
    +

    <%= f.text_field :name, :required => true, :size => 60 %>

    + <% @group.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :group, value %>

    + <% end %> +
    diff --git a/app/views/groups/_general.html.erb b/app/views/groups/_general.html.erb new file mode 100644 index 000000000..8c720c3ee --- /dev/null +++ b/app/views/groups/_general.html.erb @@ -0,0 +1,4 @@ +<%= labelled_form_for @group do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/groups/_memberships.html.erb b/app/views/groups/_memberships.html.erb new file mode 100644 index 000000000..b21958e28 --- /dev/null +++ b/app/views/groups/_memberships.html.erb @@ -0,0 +1,65 @@ +<% roles = Role.find_all_givable %> +<% projects = Project.active.all %> + +
    +<% if @group.memberships.any? %> + + + + + + + + <% @group.memberships.each do |membership| %> + <% next if membership.new_record? %> + + + + + +<% end; reset_cycle %> + +
    <%= l(:label_project) %><%= l(:label_role_plural) %>
    <%= link_to_project membership.project %> + <%=h membership.roles.sort.collect(&:to_s).join(', ') %> + <%= 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 %> +

    <% roles.each do |role| %> +
    + <% end %>

    +

    <%= submit_tag l(:button_change) %> + <%= link_to_function( + l(:button_cancel), + "$('#member-#{membership.id}-roles').show(); $('#member-#{membership.id}-roles-form').hide(); return false;" + ) %>

    + <% end %> +
    + <%= 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) %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> +
    + +
    +<% if projects.any? %> +
    <%=l(:label_project_new)%> +<%= 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) %> +

    <%= l(:label_role_plural) %>: +<% roles.each do |role| %> + +<% end %>

    +

    <%= submit_tag l(:button_add) %>

    +<% end %> +
    +<% end %> +
    diff --git a/app/views/groups/_users.html.erb b/app/views/groups/_users.html.erb new file mode 100644 index 000000000..a0f89d76f --- /dev/null +++ b/app/views/groups/_users.html.erb @@ -0,0 +1,39 @@ +
    +<% if @group.users.any? %> + + + + + + + <% @group.users.sort.each do |user| %> + + + + + <% end %> + +
    <%= l(:label_user) %>
    <%= link_to_user user %> + <%= delete_link group_user_path(@group, :user_id => user), :remote => true %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> +
    + +
    + <%= form_for(@group, :remote => true, :url => group_users_path(@group), + :html => {:method => :post}) do |f| %> +
    <%=l(:label_user_new)%> + +

    <%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %>

    + <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %> + +
    + <%= render_principals_for_new_group_users(@group) %> +
    + +

    <%= submit_tag l(:button_add) %>

    +
    + <% end %> +
    diff --git a/app/views/groups/add_users.js.erb b/app/views/groups/add_users.js.erb new file mode 100644 index 000000000..460527b6c --- /dev/null +++ b/app/views/groups/add_users.js.erb @@ -0,0 +1,4 @@ +$('#tab-content-users').html('<%= escape_javascript(render :partial => 'groups/users') %>'); +<% @users.each do |user| %> + $('#user-<%= user.id %>').effect("highlight"); +<% end %> diff --git a/app/views/groups/autocomplete_for_user.js.erb b/app/views/groups/autocomplete_for_user.js.erb new file mode 100644 index 000000000..9bb569ea1 --- /dev/null +++ b/app/views/groups/autocomplete_for_user.js.erb @@ -0,0 +1 @@ +$('#users').html('<%= escape_javascript(render_principals_for_new_group_users(@group)) %>'); diff --git a/app/views/groups/destroy_membership.js.erb b/app/views/groups/destroy_membership.js.erb new file mode 100644 index 000000000..30ab3b081 --- /dev/null +++ b/app/views/groups/destroy_membership.js.erb @@ -0,0 +1 @@ +$('#tab-content-memberships').html('<%= escape_javascript(render :partial => 'groups/memberships') %>'); diff --git a/app/views/groups/edit.html.erb b/app/views/groups/edit.html.erb new file mode 100644 index 000000000..2dd5c643c --- /dev/null +++ b/app/views/groups/edit.html.erb @@ -0,0 +1,5 @@ +

    <%= link_to l(:label_group_plural), groups_path %> » <%= h(@group) %>

    + +<%= render_tabs group_settings_tabs %> + +<% html_title(l(:label_group), @group, l(:label_administration)) -%> diff --git a/app/views/groups/edit_membership.js.erb b/app/views/groups/edit_membership.js.erb new file mode 100644 index 000000000..679c99869 --- /dev/null +++ b/app/views/groups/edit_membership.js.erb @@ -0,0 +1,6 @@ +<% if @membership.valid? %> + $('#tab-content-memberships').html('<%= escape_javascript(render :partial => 'groups/memberships') %>'); + $('#member-<%= @membership.id %>').effect("highlight"); +<% else %> + alert('<%= raw(escape_javascript(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))) %>'); +<% end %> diff --git a/app/views/groups/index.api.rsb b/app/views/groups/index.api.rsb new file mode 100644 index 000000000..6a4efeaf7 --- /dev/null +++ b/app/views/groups/index.api.rsb @@ -0,0 +1,10 @@ +api.array :groups do + @groups.each do |group| + api.group do + api.id group.id + api.name group.lastname + + render_api_custom_values group.visible_custom_field_values, api + end + end +end diff --git a/app/views/groups/index.html.erb b/app/views/groups/index.html.erb new file mode 100644 index 000000000..a93354baa --- /dev/null +++ b/app/views/groups/index.html.erb @@ -0,0 +1,26 @@ +
    +<%= link_to l(:label_group_new), new_group_path, :class => 'icon icon-add' %> +
    + +

    <%= l(:label_group_plural) %>

    + +<% if @groups.any? %> + + + + + + + +<% @groups.each do |group| %> + + + + + +<% end %> + +
    <%=l(:label_group)%><%=l(:label_user_plural)%>
    <%= link_to h(group), edit_group_path(group) %><%= group.users.size %><%= delete_link group %>
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> diff --git a/app/views/groups/new.html.erb b/app/views/groups/new.html.erb new file mode 100644 index 000000000..20ef7a2a1 --- /dev/null +++ b/app/views/groups/new.html.erb @@ -0,0 +1,9 @@ +

    <%= link_to l(:label_group_plural), groups_path %> » <%= l(:label_group_new) %>

    + +<%= labelled_form_for @group do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +

    + <%= f.submit l(:button_create) %> + <%= f.submit l(:button_create_and_continue), :name => 'continue' %> +

    +<% end %> diff --git a/app/views/groups/remove_user.js.erb b/app/views/groups/remove_user.js.erb new file mode 100644 index 000000000..88daa8f58 --- /dev/null +++ b/app/views/groups/remove_user.js.erb @@ -0,0 +1 @@ +$('#tab-content-users').html('<%= escape_javascript(render :partial => 'groups/users') %>'); diff --git a/app/views/groups/show.api.rsb b/app/views/groups/show.api.rsb new file mode 100644 index 000000000..626474410 --- /dev/null +++ b/app/views/groups/show.api.rsb @@ -0,0 +1,30 @@ +api.group do + api.id @group.id + api.name @group.lastname + + render_api_custom_values @group.visible_custom_field_values, api + + api.array :users do + @group.users.each do |user| + api.user :id => user.id, :name => user.name + end + end if include_in_api_response?('users') + + api.array :memberships do + @group.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') +end diff --git a/app/views/groups/show.html.erb b/app/views/groups/show.html.erb new file mode 100644 index 000000000..4b067454b --- /dev/null +++ b/app/views/groups/show.html.erb @@ -0,0 +1,7 @@ +

    <%= link_to l(:label_group_plural), groups_path %> » <%=h @group %>

    + +
      +<% @group.users.each do |user| %> +
    • <%=h user %>
    • +<% end %> +
    diff --git a/app/views/issue_categories/_form.html.erb b/app/views/issue_categories/_form.html.erb new file mode 100644 index 000000000..c3b20936c --- /dev/null +++ b/app/views/issue_categories/_form.html.erb @@ -0,0 +1,6 @@ +<%= error_messages_for 'category' %> + +
    +

    <%= f.text_field :name, :size => 30, :required => true %>

    +

    <%= f.select :assigned_to_id, principals_options_for_select(@project.assignable_users, @category.assigned_to), :include_blank => true %>

    +
    diff --git a/app/views/issue_categories/_new_modal.html.erb b/app/views/issue_categories/_new_modal.html.erb new file mode 100644 index 000000000..07cc289ff --- /dev/null +++ b/app/views/issue_categories/_new_modal.html.erb @@ -0,0 +1,9 @@ +

    <%=l(:label_issue_category_new)%>

    + +<%= labelled_form_for @category, :as => 'issue_category', :url => project_issue_categories_path(@project), :remote => true do |f| %> +<%= render :partial => 'issue_categories/form', :locals => { :f => f } %> +

    + <%= submit_tag l(:button_create), :name => nil %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

    +<% end %> diff --git a/app/views/issue_categories/create.js.erb b/app/views/issue_categories/create.js.erb new file mode 100644 index 000000000..c4253b98e --- /dev/null +++ b/app/views/issue_categories/create.js.erb @@ -0,0 +1,3 @@ +hideModal(); +<% select = content_tag('select', content_tag('option') + options_from_collection_for_select(@project.issue_categories, 'id', 'name', @category.id), :id => 'issue_category_id', :name => 'issue[category_id]') %> +$('#issue_category_id').replaceWith('<%= escape_javascript(select) %>'); diff --git a/app/views/issue_categories/destroy.html.erb b/app/views/issue_categories/destroy.html.erb new file mode 100644 index 000000000..ae14c5ec5 --- /dev/null +++ b/app/views/issue_categories/destroy.html.erb @@ -0,0 +1,16 @@ +

    <%=l(:label_issue_category)%>: <%=h @category.name %>

    + +<%= form_tag(issue_category_path(@category), :method => :delete) do %> +
    +

    <%= l(:text_issue_category_destroy_question, @issue_count) %>

    +


    +<% if @categories.size > 0 %> +: +<%= 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') %>

    +<% end %> +
    + +<%= submit_tag l(:button_apply) %> +<%= link_to l(:button_cancel), :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' %> +<% end %> diff --git a/app/views/issue_categories/edit.html.erb b/app/views/issue_categories/edit.html.erb new file mode 100644 index 000000000..fd5f7cc85 --- /dev/null +++ b/app/views/issue_categories/edit.html.erb @@ -0,0 +1,7 @@ +

    <%=l(:label_issue_category)%>

    + +<%= labelled_form_for @category, :as => :issue_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 --git a/app/views/issue_categories/index.api.rsb b/app/views/issue_categories/index.api.rsb new file mode 100644 index 000000000..685d8a560 --- /dev/null +++ b/app/views/issue_categories/index.api.rsb @@ -0,0 +1,10 @@ +api.array :issue_categories, api_meta(:total_count => @categories.size) do + @categories.each do |category| + api.issue_category do + api.id category.id + api.project(:id => category.project_id, :name => category.project.name) unless category.project.nil? + api.name category.name + api.assigned_to(:id => category.assigned_to_id, :name => category.assigned_to.name) unless category.assigned_to.nil? + end + end +end diff --git a/app/views/issue_categories/new.html.erb b/app/views/issue_categories/new.html.erb new file mode 100644 index 000000000..e042b8922 --- /dev/null +++ b/app/views/issue_categories/new.html.erb @@ -0,0 +1,7 @@ +

    <%=l(:label_issue_category_new)%>

    + +<%= labelled_form_for @category, :as => :issue_category, + :url => project_issue_categories_path(@project) do |f| %> +<%= render :partial => 'issue_categories/form', :locals => { :f => f } %> +<%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/issue_categories/new.js.erb b/app/views/issue_categories/new.js.erb new file mode 100644 index 000000000..0d623495e --- /dev/null +++ b/app/views/issue_categories/new.js.erb @@ -0,0 +1,2 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'issue_categories/new_modal') %>'); +showModal('ajax-modal', '600px'); diff --git a/app/views/issue_categories/show.api.rsb b/app/views/issue_categories/show.api.rsb new file mode 100644 index 000000000..cefa7c8b8 --- /dev/null +++ b/app/views/issue_categories/show.api.rsb @@ -0,0 +1,6 @@ +api.issue_category do + api.id @category.id + api.project(:id => @category.project_id, :name => @category.project.name) unless @category.project.nil? + api.name @category.name + api.assigned_to(:id => @category.assigned_to_id, :name => @category.assigned_to.name) unless @category.assigned_to.nil? +end diff --git a/app/views/issue_relations/_form.html.erb b/app/views/issue_relations/_form.html.erb new file mode 100644 index 000000000..29b7f0f14 --- /dev/null +++ b/app/views/issue_relations/_form.html.erb @@ -0,0 +1,14 @@ +<%= error_messages_for 'relation' %> + +

    <%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %> +<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :size => 10 %> + +<%= submit_tag l(:button_add) %> +<%= link_to_function l(:button_cancel), '$("#new-relation-form").hide();'%> +

    + +<%= javascript_tag "observeAutocompleteField('relation_issue_to_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (Setting.cross_project_issue_relations? ? 'all' : nil))}')" %> + +<%= javascript_tag "setPredecessorFieldsVisibility();" %> diff --git a/app/views/issue_relations/create.js.erb b/app/views/issue_relations/create.js.erb new file mode 100644 index 000000000..03ba21975 --- /dev/null +++ b/app/views/issue_relations/create.js.erb @@ -0,0 +1,6 @@ +$('#relations').html('<%= escape_javascript(render :partial => 'issues/relations') %>'); +<% if @relation.errors.empty? %> + $('#relation_delay').val(''); + $('#relation_issue_to_id').val(''); + $('#relation_issue_to_id').focus(); +<% end %> diff --git a/app/views/issue_relations/destroy.js.erb b/app/views/issue_relations/destroy.js.erb new file mode 100644 index 000000000..f5f29d31d --- /dev/null +++ b/app/views/issue_relations/destroy.js.erb @@ -0,0 +1 @@ +$('#relation-<%= @relation.id %>').remove(); diff --git a/app/views/issue_relations/index.api.rsb b/app/views/issue_relations/index.api.rsb new file mode 100644 index 000000000..11ff3094b --- /dev/null +++ b/app/views/issue_relations/index.api.rsb @@ -0,0 +1,11 @@ +api.array :relations do + @relations.each do |relation| + api.relation do + api.id relation.id + api.issue_id relation.issue_from_id + api.issue_to_id relation.issue_to_id + api.relation_type relation.relation_type + api.delay relation.delay + end + end +end diff --git a/app/views/issue_relations/show.api.rsb b/app/views/issue_relations/show.api.rsb new file mode 100644 index 000000000..bffad94ab --- /dev/null +++ b/app/views/issue_relations/show.api.rsb @@ -0,0 +1,7 @@ +api.relation do + api.id @relation.id + api.issue_id @relation.issue_from_id + api.issue_to_id @relation.issue_to_id + api.relation_type @relation.relation_type + api.delay @relation.delay +end diff --git a/app/views/issue_statuses/_form.html.erb b/app/views/issue_statuses/_form.html.erb new file mode 100644 index 000000000..37898737c --- /dev/null +++ b/app/views/issue_statuses/_form.html.erb @@ -0,0 +1,12 @@ +<%= error_messages_for 'issue_status' %> + +
    +

    <%= f.text_field :name, :required => true %>

    +<% if Issue.use_status_for_done_ratio? %> +

    <%= f.select :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :include_blank => true, :label => :field_done_ratio %>

    +<% end %> +

    <%= f.check_box :is_closed %>

    +

    <%= f.check_box :is_default %>

    + +<%= call_hook(:view_issue_statuses_form, :issue_status => @issue_status) %> +
    diff --git a/app/views/issue_statuses/edit.html.erb b/app/views/issue_statuses/edit.html.erb new file mode 100644 index 000000000..c2eace1ca --- /dev/null +++ b/app/views/issue_statuses/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to l(:label_issue_status_plural), issue_statuses_path %> » <%=h @issue_status %>

    + +<%= labelled_form_for @issue_status do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/issue_statuses/index.api.rsb b/app/views/issue_statuses/index.api.rsb new file mode 100644 index 000000000..8a51674d9 --- /dev/null +++ b/app/views/issue_statuses/index.api.rsb @@ -0,0 +1,10 @@ +api.array :issue_statuses do + @issue_statuses.each do |status| + api.issue_status do + api.id status.id + api.name status.name + api.is_default status.is_default + api.is_closed status.is_closed + end + end +end diff --git a/app/views/issue_statuses/index.html.erb b/app/views/issue_statuses/index.html.erb new file mode 100644 index 000000000..f0a5e850d --- /dev/null +++ b/app/views/issue_statuses/index.html.erb @@ -0,0 +1,39 @@ +
    +<%= 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', :data => {:confirm => l(:text_are_you_sure)}) if Issue.use_status_for_done_ratio? %> +
    + +

    <%=l(:label_issue_status_plural)%>

    + + + + + <% if Issue.use_status_for_done_ratio? %> + + <% end %> + + + + + + +<% for status in @issue_statuses %> + "> + + <% if Issue.use_status_for_done_ratio? %> + + <% end %> + + + + + +<% end %> + +
    <%=l(:field_status)%><%=l(:field_done_ratio)%><%=l(:field_is_default)%><%=l(:field_is_closed)%><%=l(:button_sort)%>
    <%= link_to h(status.name), edit_issue_status_path(status) %><%= h status.default_done_ratio %><%= checked_image status.is_default? %><%= checked_image status.is_closed? %><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %> + <%= delete_link issue_status_path(status) %> +
    + +

    <%= pagination_links_full @issue_status_pages %>

    + +<% html_title(l(:label_issue_status_plural)) -%> diff --git a/app/views/issue_statuses/new.html.erb b/app/views/issue_statuses/new.html.erb new file mode 100644 index 000000000..a5730e6bf --- /dev/null +++ b/app/views/issue_statuses/new.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to l(:label_issue_status_plural), issue_statuses_path %> » <%=l(:label_issue_status_new)%>

    + +<%= labelled_form_for @issue_status do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/issues/_action_menu.html.erb b/app/views/issues/_action_menu.html.erb new file mode 100644 index 000000000..4757ebcba --- /dev/null +++ b/app/views/issues/_action_menu.html.erb @@ -0,0 +1,7 @@ +
    +<%= 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) %> +
    diff --git a/app/views/issues/_attributes.html.erb b/app/views/issues/_attributes.html.erb new file mode 100644 index 000000000..9b4c508cd --- /dev/null +++ b/app/views/issues/_attributes.html.erb @@ -0,0 +1,73 @@ +<%= labelled_fields_for :issue, @issue do |f| %> + +
    +
    +<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %> +

    <%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true}, + :onchange => "updateIssueFrom('#{escape_javascript project_issue_form_path(@project, :id => @issue, :format => 'js')}')" %>

    + +<% else %> +

    <%= h(@issue.status.name) %>

    +<% end %> + +<% if @issue.safe_attribute? 'priority_id' %> +

    <%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), {:required => true}, :disabled => !@issue.leaf? %>

    +<% end %> + +<% if @issue.safe_attribute? 'assigned_to_id' %> +

    <%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true, :required => @issue.required_attribute?('assigned_to_id') %>

    +<% end %> + +<% if @issue.safe_attribute?('category_id') && @issue.project.issue_categories.any? %> +

    <%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true, :required => @issue.required_attribute?('category_id') %> +<%= link_to(image_tag('add.png', :style => 'vertical-align: middle;'), + new_project_issue_category_path(@issue.project), + :remote => true, + :method => 'get', + :title => l(:label_issue_category_new), + :tabindex => 200) if User.current.allowed_to?(:manage_categories, @issue.project) %>

    +<% end %> + +<% if @issue.safe_attribute?('fixed_version_id') && @issue.assignable_versions.any? %> +

    <%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true, :required => @issue.required_attribute?('fixed_version_id') %> +<%= link_to(image_tag('add.png', :style => 'vertical-align: middle;'), + new_project_version_path(@issue.project), + :remote => true, + :method => 'get', + :title => l(:label_version_new), + :tabindex => 200) if User.current.allowed_to?(:manage_versions, @issue.project) %> +

    +<% end %> +
    + +
    +<% if @issue.safe_attribute? 'parent_issue_id' %> +

    <%= f.text_field :parent_issue_id, :size => 10, :required => @issue.required_attribute?('parent_issue_id') %>

    +<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path}')" %> +<% end %> + +<% if @issue.safe_attribute? 'start_date' %> +

    <%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('start_date') %><%= calendar_for('issue_start_date') if @issue.leaf? %>

    +<% end %> + +<% if @issue.safe_attribute? 'due_date' %> +

    <%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('due_date') %><%= calendar_for('issue_due_date') if @issue.leaf? %>

    +<% end %> + +<% if @issue.safe_attribute? 'estimated_hours' %> +

    <%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %>

    +<% end %> + +<% if @issue.safe_attribute?('done_ratio') && @issue.leaf? && Issue.use_field_for_done_ratio? %> +

    <%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :required => @issue.required_attribute?('done_ratio') %>

    +<% end %> +
    +
    + +<% if @issue.safe_attribute? 'custom_field_values' %> +<%= render :partial => 'issues/form_custom_fields' %> +<% end %> + +<% end %> + +<% include_calendar_headers_tags %> diff --git a/app/views/issues/_changesets.html.erb b/app/views/issues/_changesets.html.erb new file mode 100644 index 000000000..beab65536 --- /dev/null +++ b/app/views/issues/_changesets.html.erb @@ -0,0 +1,10 @@ +<% changesets.each do |changeset| %> +
    +

    <%= link_to_revision(changeset, changeset.repository, + :text => "#{l(:label_revision)} #{changeset.format_identifier}") %>
    + <%= authoring(changeset.committed_on, changeset.author) %>

    +
    + <%= textilizable(changeset, :comments) %> +
    +
    +<% end %> diff --git a/app/views/issues/_conflict.html.erb b/app/views/issues/_conflict.html.erb new file mode 100644 index 000000000..01d668821 --- /dev/null +++ b/app/views/issues/_conflict.html.erb @@ -0,0 +1,26 @@ +
    + <%= l(:notice_issue_update_conflict) %> + <% if @conflict_journals.present? %> +
    + <% @conflict_journals.sort_by(&:id).each do |journal| %> +

    <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %>

    + <% if journal.details.any? %> +
      + <% details_to_strings(journal.details).each do |string| %> +
    • <%= string %>
    • + <% end %> +
    + <% end %> + <%= textilizable(journal, :notes) unless journal.notes.blank? %> + <% end %> +
    + <% end %> +
    +

    +
    + <% if @issue.notes.present? %> +
    + <% end %> + +

    +

    <%= submit_tag l(:button_submit) %>

    diff --git a/app/views/issues/_edit.html.erb b/app/views/issues/_edit.html.erb new file mode 100644 index 000000000..f2052a27a --- /dev/null +++ b/app/views/issues/_edit.html.erb @@ -0,0 +1,51 @@ +<%= labelled_form_for @issue, :html => {:id => 'issue-form', :multipart => true} do |f| %> + <%= error_messages_for 'issue', 'time_entry' %> + <%= render :partial => 'conflict' if @conflict %> +
    + <% if @edit_allowed || !@allowed_statuses.empty? %> +
    <%= l(:label_change_properties) %> +
    + <%= render :partial => 'form', :locals => {:f => f} %> +
    +
    + <% end %> + <% if User.current.allowed_to?(:log_time, @project) %> +
    <%= l(:button_log_time) %> + <%= labelled_fields_for :time_entry, @time_entry do |time_entry| %> +
    +

    <%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %>

    +
    +
    +

    <%= time_entry.select :activity_id, activity_collection_for_select_options %>

    +
    +

    <%= time_entry.text_field :comments, :size => 60 %>

    + <% @time_entry.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :time_entry, value %>

    + <% end %> + <% end %> +
    + <% end %> + +
    <%= l(:field_notes) %> + <%= f.text_area :notes, :cols => 60, :rows => 10, :class => 'wiki-edit', :no_label => true %> + <%= wikitoolbar_for 'issue_notes' %> + + <% if @issue.safe_attribute? 'private_notes' %> + + <% end %> + + <%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %> +
    + +
    <%= l(:label_attachment_plural) %> +

    <%= render :partial => 'attachments/form', :locals => {:container => @issue} %>

    +
    +
    + + <%= f.hidden_field :lock_version %> + <%= hidden_field_tag 'last_journal_id', params[:last_journal_id] || @issue.last_journal_id %> + <%= submit_tag l(:button_submit) %> + <%= preview_link preview_edit_issue_path(:project_id => @project, :id => @issue), 'issue-form' %> +<% end %> + +
    diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb new file mode 100644 index 000000000..6a79d1e50 --- /dev/null +++ b/app/views/issues/_form.html.erb @@ -0,0 +1,45 @@ +<%= labelled_fields_for :issue, @issue do |f| %> +<%= call_hook(:view_issues_form_details_top, { :issue => @issue, :form => f }) %> + +<% if @issue.safe_attribute? 'is_private' %> +

    + <%= f.check_box :is_private, :no_label => true %> +

    +<% end %> + +<% if @issue.safe_attribute? 'project_id' %> +

    <%= f.select :project_id, project_tree_options_for_select(@issue.allowed_target_projects, :selected => @issue.project), {:required => true}, + :onchange => "updateIssueFrom('#{escape_javascript project_issue_form_path(@project, :id => @issue, :format => 'js')}')" %>

    +<% end %> + +<% if @issue.safe_attribute? 'tracker_id' %> +

    <%= f.select :tracker_id, @issue.project.trackers.collect {|t| [t.name, t.id]}, {:required => true}, + :onchange => "updateIssueFrom('#{escape_javascript project_issue_form_path(@project, :id => @issue, :format => 'js')}')" %>

    +<% end %> + +<% if @issue.safe_attribute? 'subject' %> +

    <%= f.text_field :subject, :size => 80, :maxlength => 255, :required => true %>

    +<% end %> + +<% if @issue.safe_attribute? 'description' %> +

    + <%= f.label_for_field :description, :required => @issue.required_attribute?('description') %> + <%= link_to_function image_tag('edit.png'), '$(this).hide(); $("#issue_description_and_toolbar").show()' unless @issue.new_record? %> + <%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@issue.new_record? ? nil : 'display:none') do %> + <%= 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', + :no_label => true %> + <% end %> +

    +<%= wikitoolbar_for 'issue_description' %> +<% end %> + +
    + <%= render :partial => 'issues/attributes' %> +
    + +<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %> +<% end %> diff --git a/app/views/issues/_form_custom_fields.html.erb b/app/views/issues/_form_custom_fields.html.erb new file mode 100644 index 000000000..4da98eb13 --- /dev/null +++ b/app/views/issues/_form_custom_fields.html.erb @@ -0,0 +1,13 @@ +
    +
    +<% i = 0 %> +<% split_on = (@issue.custom_field_values.size / 2.0).ceil - 1 %> +<% @issue.editable_custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %>

    +<% if i == split_on -%> +
    +<% end -%> +<% i += 1 -%> +<% end -%> +
    +
    diff --git a/app/views/issues/_history.html.erb b/app/views/issues/_history.html.erb new file mode 100644 index 000000000..470a55acf --- /dev/null +++ b/app/views/issues/_history.html.erb @@ -0,0 +1,22 @@ +<% reply_links = authorize_for('issues', 'edit') -%> +<% for journal in journals %> +
    +
    +

    <%= link_to "##{journal.indice}", {:anchor => "note-#{journal.indice}"}, :class => "journal-link" %> + <%= avatar(journal.user, :size => "24") %> + <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %>

    + + <% if journal.details.any? %> +
      + <% details_to_strings(journal.details).each do |string| %> +
    • <%= string %>
    • + <% end %> +
    + <% end %> + <%= render_notes(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %> +
    +
    + <%= 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 --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb new file mode 100644 index 000000000..f323e3783 --- /dev/null +++ b/app/views/issues/_list.html.erb @@ -0,0 +1,108 @@ +<%= form_tag({}) do -%> +<%= hidden_field_tag 'back_url', url_for(params), :id => nil %> +
    + + + + + + +
      + + <% issue_list(issues) do |issue, level| -%> + <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %> + <% reset_cycle %> + + +   + <%= group.blank? ? l(:label_none) : column_content(@query.group_by_column, issue) %> <%= @issue_count_by_group[group] %> + <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", + "toggleAllRowGroups(this)", :class => 'toggle-all') %> + + + <% previous_group = group %> + <% end %> + +
    • "> + <% column_content = ( query.inline_columns.map {|column| "
    • #{column_content(column, issue)}
    • "}) %> +
        + <%= raw column_content[0] %> + <%= raw column_content[4] %> +
          + <%= l(:label_type_as)%><%= raw column_content[1] %> + <%= l(:label_status_as)%><%= raw column_content[2] %> + <%= l(:label_priority_as)%><%= raw column_content[3] %> + <% unless issue.assigned_to_id.nil? %> + <%= l(:field_assigned_to)%><%= raw column_content[5] %> + <% end %> + + <%= l(:label_updated_time, time_tag(issue.updated_on)).html_safe %> +
        +
      + + + <% @query.block_columns.each do |column| + if (text = column_content(column, issue)) && text.present? -%> + + <%= text %> + + <% end -%> + <% end -%> + <% end -%> + +
    +
    +<% end -%> diff --git a/app/views/issues/_list_simple.html.erb b/app/views/issues/_list_simple.html.erb new file mode 100644 index 000000000..0e4aa0731 --- /dev/null +++ b/app/views/issues/_list_simple.html.erb @@ -0,0 +1,29 @@ +<% if issues && issues.any? %> +<%= form_tag({}) do %> + + + + + + + + + <% for issue in issues %> + + + + + + + <% end %> + +
    #<%=l(:field_project)%><%=l(:field_tracker)%><%=l(:field_subject)%>
    + <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %> + <%= link_to issue.id, issue_path(issue) %> + <%= link_to_project(issue.project) %><%=h issue.tracker %> + <%= link_to truncate(issue.subject, :length => 60), issue_path(issue) %> (<%=h issue.status %>) +
    +<% end %> +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> diff --git a/app/views/issues/_relations.html.erb b/app/views/issues/_relations.html.erb new file mode 100644 index 000000000..0cffa8f53 --- /dev/null +++ b/app/views/issues/_relations.html.erb @@ -0,0 +1,44 @@ +
    +<% if User.current.allowed_to?(:manage_issue_relations, @project) %> + <%= toggle_link l(:button_add), 'new-relation-form', {:focus => 'relation_issue_to_id'} %> +<% end %> +
    + +

    <%=l(:label_related_issues)%>

    + +<% if @relations.present? %> +
    + +<% @relations.each do |relation| %> + <% other_issue = relation.other_issue(@issue) -%> + + + + + + + + +<% end %> +
    <%= check_box_tag("ids[]", other_issue.id, false, :id => nil) %> + <%= 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) %> + <%=h other_issue.status.name %><%= format_date(other_issue.start_date) %><%= format_date(other_issue.due_date) %><%= 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) %>
    +
    +<% 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 --git a/app/views/issues/_sidebar.html.erb b/app/views/issues/_sidebar.html.erb new file mode 100644 index 000000000..24b8a4fa4 --- /dev/null +++ b/app/views/issues/_sidebar.html.erb @@ -0,0 +1,17 @@ +

    <%= l(:label_issue_plural) %>

    +<%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %>
    +<% if @project %> +<%= link_to l(:field_summary), project_issues_report_path(@project) %>
    +<% 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) %>
    +<% end %> +<% if User.current.allowed_to?(:view_gantt, @project, :global => true) %> + <%= link_to l(:label_gantt), _project_gantt_path(@project) %>
    +<% end %> +<%= call_hook(:view_issues_sidebar_planning_bottom) %> + +<%= render_sidebar_queries %> +<%= call_hook(:view_issues_sidebar_queries_bottom) %> diff --git a/app/views/issues/bulk_edit.html.erb b/app/views/issues/bulk_edit.html.erb new file mode 100644 index 000000000..281c7a309 --- /dev/null +++ b/app/views/issues/bulk_edit.html.erb @@ -0,0 +1,150 @@ +

    <%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %>

    + +
      +<% @issues.each do |issue| %> + <%= content_tag 'li', link_to_issue(issue) %> +<% end %> +
    + +<%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %> +<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> +
    +
    +<%= l(:label_change_properties) %> + +
    +<% if @allowed_projects.present? %> +

    + + <%= 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')}')") %> +

    +<% end %> +

    + + <%= select_tag('issue[tracker_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@trackers, :id, :name)) %> +

    +<% if @available_statuses.any? %> +

    + + <%= select_tag('issue[status_id]',content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_statuses, :id, :name)) %> +

    +<% end %> + +<% if @safe_attributes.include?('priority_id') -%> +

    + + <%= select_tag('issue[priority_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(IssuePriority.active, :id, :name)) %> +

    +<% end %> + +<% if @safe_attributes.include?('assigned_to_id') -%> +

    + + <%= 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)) %> +

    +<% end %> + +<% if @safe_attributes.include?('category_id') -%> +

    + + <%= 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)) %> +

    +<% end %> + +<% if @safe_attributes.include?('fixed_version_id') -%> +

    + + <%= 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)) %> +

    +<% end %> + +<% @custom_fields.each do |custom_field| %> +

    <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %>

    +<% end %> + +<% if @copy && @attachments_present %> +

    + + <%= check_box_tag 'copy_attachments', '1', true %> +

    +<% end %> + +<% if @copy && @subtasks_present %> +

    + + <%= check_box_tag 'copy_subtasks', '1', true %> +

    +<% end %> + +<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %> +
    + +
    +<% if @safe_attributes.include?('is_private') %> +

    + + <%= 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')) %> +

    +<% end %> + +<% if @safe_attributes.include?('parent_issue_id') && @project %> +

    + + <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %> +

    +<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %> +<% end %> + +<% if @safe_attributes.include?('start_date') %> +

    + + <%= text_field_tag 'issue[start_date]', '', :size => 10 %><%= calendar_for('issue_start_date') %> +

    +<% end %> + +<% if @safe_attributes.include?('due_date') %> +

    + + <%= text_field_tag 'issue[due_date]', '', :size => 10 %><%= calendar_for('issue_due_date') %> +

    +<% end %> + +<% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %> +

    + + <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %> +

    +<% end %> +
    + +
    + +
    <%= l(:field_notes) %> +<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> +<%= wikitoolbar_for 'notes' %> +
    +
    + +

    + <% 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 %> +

    + +<% end %> diff --git a/app/views/issues/bulk_edit.js.erb b/app/views/issues/bulk_edit.js.erb new file mode 100644 index 000000000..ac84ad1d9 --- /dev/null +++ b/app/views/issues/bulk_edit.js.erb @@ -0,0 +1 @@ +$('#content').html('<%= escape_javascript(render :template => 'issues/bulk_edit', :formats => [:html]) %>'); diff --git a/app/views/issues/destroy.html.erb b/app/views/issues/destroy.html.erb new file mode 100644 index 000000000..cffea742f --- /dev/null +++ b/app/views/issues/destroy.html.erb @@ -0,0 +1,15 @@ +

    <%= l(:label_confirmation) %>

    + +<%= form_tag({}, :method => :delete) do %> +<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> +
    +

    <%= l(:text_destroy_time_entries_question, :hours => number_with_precision(@hours, :precision => 2)) %>

    +

    +
    +
    + +<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %> +

    +
    +<%= submit_tag l(:button_apply) %> +<% end %> diff --git a/app/views/issues/edit.html.erb b/app/views/issues/edit.html.erb new file mode 100644 index 000000000..83f02051e --- /dev/null +++ b/app/views/issues/edit.html.erb @@ -0,0 +1,6 @@ +

    <%=h "#{@issue.tracker.name} ##{@issue.id}" %>

    + +<%= render :partial => 'edit' %> +<% content_for :header_tags do %> + <%= robot_exclusion_tag %> +<% end %> diff --git a/app/views/issues/index.api.rsb b/app/views/issues/index.api.rsb new file mode 100644 index 000000000..5009ffa7e --- /dev/null +++ b/app/views/issues/index.api.rsb @@ -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 --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb new file mode 100644 index 000000000..3d54e9cb3 --- /dev/null +++ b/app/views/issues/index.html.erb @@ -0,0 +1,121 @@ +
    + <% 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 %> +
    + +<% 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' %> +
    +
    "> + + <%= l(:label_filter_plural) %> + +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    + +
    +

    + + <%= 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' %> + <%= link_to l(:label_issue_new), { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new, + :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }, :class => 'icon icon-add' %> + <% 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 %> +

    +<% end %> + +<%= error_messages_for 'query' %> +<% if @query.valid? %> +<% if @issues.empty? %> +

    + <%= l(:label_no_data) %> +

    +<% else %> +<%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %> + + +<% 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 %> + + + +<% 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 --git a/app/views/issues/new.html.erb b/app/views/issues/new.html.erb new file mode 100644 index 000000000..82b3f6f91 --- /dev/null +++ b/app/views/issues/new.html.erb @@ -0,0 +1,53 @@ +<%= call_hook(:view_issues_new_top, {:issue => @issue}) %> + +<%= labelled_form_for @issue, :url => project_issues_path(@project), + :html => {:id => 'issue-form', :multipart => true} do |f| %> + <%= error_messages_for 'issue' %> + <%= hidden_field_tag 'copy_from', params[:copy_from] if params[:copy_from] %> +
    +
    + <%= render :partial => 'issues/form', :locals => {:f => f} %> +
    + + <% if @copy_from && @copy_from.attachments.any? %> +

    + + <%= check_box_tag 'copy_attachments', '1', @copy_attachments %> +

    + <% end %> + <% if @copy_from && !@copy_from.leaf? %> +

    + + <%= check_box_tag 'copy_subtasks', '1', @copy_subtasks %> +

    + <% end %> + +

    <%= render :partial => 'attachments/form', :locals => {:container => @issue} %>

    + + <% if @issue.safe_attribute? 'watcher_user_ids' -%> +

    + + <%= watchers_checkboxes(@issue, @available_watchers) %> + + + <%= link_to l(:label_search_for_watchers), + {:controller => 'watchers', :action => 'new', :project_id => @issue.project}, + :remote => true, + :method => 'get' %> + +

    + <% end %> +
    + + <%= submit_tag l(:button_create) %> + <%= submit_tag l(:button_create_and_continue), :name => 'continue' %> + <%= preview_link preview_new_issue_path(:project_id => @project), 'issue-form' %> + + <%= javascript_tag "$('#issue_subject').focus();" %> +<% end %> + +
    + +<% content_for :header_tags do %> + <%= robot_exclusion_tag %> +<% end %> diff --git a/app/views/issues/show.api.rsb b/app/views/issues/show.api.rsb new file mode 100644 index 000000000..ce788a723 --- /dev/null +++ b/app/views/issues/show.api.rsb @@ -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 --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb new file mode 100644 index 000000000..c7ce9a231 --- /dev/null +++ b/app/views/issues/show.html.erb @@ -0,0 +1,164 @@ +<%= render :partial => 'action_menu' %> + +

    <%= issue_heading(@issue) %>

    + +
    + <% if @prev_issue_id || @next_issue_id %> + + <% end %> + + <%= avatar(@issue.author, :size => "50") %> + + +
    +<%= render_issue_subject_with_tree(@issue) %> +
    +

    + <%= 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 %> + +

    + +
    + <%= render :partial => 'layouts/tag', :locals => {:obj => @issue,:object_flag => "3" }%> +
    + + +<%= 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) %> +
    + +<% if @issue.description? || @issue.attachments.any? -%> +
    +<% if @issue.description? %> +
    +
    + <%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if authorize_for('issues', 'edit') %> +
    + +

    <%=l(:field_description)%>

    +
    + <%= textilizable @issue, :description, :attachments => @issue.attachments %> +
    +
    +<% 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) %> +
    +
    +
    + <%= link_to_new_subtask(@issue) if User.current.allowed_to?(:manage_subtasks, @project) %> +
    +

    <%=l(:label_subtask_plural)%>

    +<%= render_descendants_tree(@issue) unless @issue.leaf? %> +
    +<% end %> + +<% if @relations.present? || User.current.allowed_to?(:manage_issue_relations, @project) %> +
    +
    +<%= render :partial => 'relations' %> +
    +<% end %> + +
    + +<% if @changesets.present? %> +
    +

    <%=l(:label_associated_revisions)%>

    +<%= render :partial => 'changesets', :locals => { :changesets => @changesets} %> +
    +<% end %> + +<% if @journals.present? %> +
    +

    <%=l(:label_history)%>

    +<%= render :partial => 'history', :locals => { :issue => @issue, :journals => @journals } %> +
    +<% end %> + + +
    +<%= render :partial => 'action_menu' %> + +
    +<% if @issue.editable? %> + +<% 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)) %> +
    + <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %> +
    + <% 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 --git a/app/views/issues/update_form.js.erb b/app/views/issues/update_form.js.erb new file mode 100644 index 000000000..46fc9722e --- /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 --git a/app/views/journals/_notes_form.html.erb b/app/views/journals/_notes_form.html.erb new file mode 100644 index 000000000..63b87883a --- /dev/null +++ b/app/views/journals/_notes_form.html.erb @@ -0,0 +1,18 @@ +<%= form_tag({:controller => 'journals', :action => 'edit', :id => @journal}, + :remote => true, + :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}) %> +

    <%= submit_tag l(:button_save) %> + <%= preview_link preview_edit_issue_path(:project_id => @project, :id => @journal.issue), + "journal-#{@journal.id}-form", + "journal_#{@journal.id}_preview" %> | + <%= link_to l(:button_cancel), '#', :onclick => "$('#journal-#{@journal.id}-form').remove(); $('#journal-#{@journal.id}-notes').show(); return false;" %>

    + +
    +<% end %> +<%= wikitoolbar_for "journal_#{@journal.id}_notes" %> diff --git a/app/views/journals/diff.html.erb b/app/views/journals/diff.html.erb new file mode 100644 index 000000000..d846b9d19 --- /dev/null +++ b/app/views/journals/diff.html.erb @@ -0,0 +1,10 @@ +

    <%=h @issue.tracker %> #<%= @issue.id %>

    +

    <%= authoring @journal.created_on, @journal.user, :label => :label_updated_time_by %>

    + +
    +<%= simple_format_without_paragraph @diff.to_html %> +
    + +

    <%= link_to l(:button_back), issue_path(@issue), :onclick => 'history.back(); return false;' %>

    + +<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %> diff --git a/app/views/journals/edit.js.erb b/app/views/journals/edit.js.erb new file mode 100644 index 000000000..96cf6b4f8 --- /dev/null +++ b/app/views/journals/edit.js.erb @@ -0,0 +1,8 @@ +$("#journal-<%= @journal.id %>-notes").hide(); + +if ($("form#journal-<%= @journal.id %>-form").length > 0) { + // journal edit form already loaded + $("#journal-<%= @journal.id %>-form").show(); +} else { + $("#journal-<%= @journal.id %>-notes").after('<%= escape_javascript(render :partial => 'notes_form') %>'); +} diff --git a/app/views/journals/index.builder b/app/views/journals/index.builder new file mode 100644 index 000000000..a81ff98a8 --- /dev/null +++ b/app/views/journals/index.builder @@ -0,0 +1,30 @@ +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! '
      ' + details_to_strings(change.details, false).each do |string| + xml.text! '
    • ' + string + '
    • ' + end + xml.text! '
    ' + xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank? + end + end + end +end diff --git a/app/views/journals/new.js.erb b/app/views/journals/new.js.erb new file mode 100644 index 000000000..78ec5f360 --- /dev/null +++ b/app/views/journals/new.js.erb @@ -0,0 +1,10 @@ +$('#issue_notes').val("<%= raw escape_javascript(@content) %>"); +<% + # when quoting a private journal, check the private checkbox + if @journal && @journal.private_notes? +%> +$('#issue_private_notes').attr('checked', true); +<% end %> + +showAndScrollTo("update", "notes"); +$('#notes').scrollTop = $('#notes').scrollHeight - $('#notes').clientHeight; diff --git a/app/views/journals/update.js.erb b/app/views/journals/update.js.erb new file mode 100644 index 000000000..65c198d59 --- /dev/null +++ b/app/views/journals/update.js.erb @@ -0,0 +1,9 @@ +<% if @journal.frozen? %> + $("#change-<%= @journal.id %>").remove(); +<% else %> + $("#journal-<%= @journal.id %>-notes").replaceWith('<%= escape_javascript(render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))) %>'); + $("#journal-<%= @journal.id %>-notes").show(); + $("#journal-<%= @journal.id %>-form").remove(); +<% end %> + +<%= call_hook(:view_journals_update_js_bottom, { :journal => @journal }) %> diff --git a/app/views/layouts/_base_header.html.erb b/app/views/layouts/_base_header.html.erb new file mode 100644 index 000000000..093ee9348 --- /dev/null +++ b/app/views/layouts/_base_header.html.erb @@ -0,0 +1,7 @@ +
    +
    + <%= render_menu :account_menu -%> +
    + <%= 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? -%> +
    \ No newline at end of file diff --git a/app/views/layouts/_tag.html.erb b/app/views/layouts/_tag.html.erb new file mode 100644 index 000000000..04c62fd1f --- /dev/null +++ b/app/views/layouts/_tag.html.erb @@ -0,0 +1,20 @@ + + + + +<%= toggle_link (image_tag "/images/add.png"), 'put-tag-form', {:focus => 'name'} %> +
    + <%= render :partial => "layouts/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> +
    + + diff --git a/app/views/layouts/_tag_name.html.erb b/app/views/layouts/_tag_name.html.erb new file mode 100644 index 000000000..d510e0030 --- /dev/null +++ b/app/views/layouts/_tag_name.html.erb @@ -0,0 +1,55 @@ + + +<% @tags = obj.reload.tag_list %> + +<% if non_list_all and (@tags.size > 0) %> + + <% if @tags.size > Setting.show_tags_length.to_i then %> + <% i = 0 %> + <% until i>Setting.show_tags_length.to_i do %> +
    + <%= link_to @tags[i], :controller => "tags",:action => "index",:q => @tags[i],:object_flag => object_flag,:obj_id => obj.id %> +
    + <% i += 1%> + <% end %> + <%= link_to l(:label_more_tags),:action => "show",:id => obj.id %> + + <% else %> + + <% @tags.each do |tag| %> +
    + <%= link_to tag,:controller => "tags",:action => "index",:q=>tag,:object_flag => object_flag,:obj_id => obj.id + %> +
    + <% end %> + <% end %> + +<% else %> + + <% if @tags.size > 0 %> + <% @tags.each do |tag| %> +
    + <%= link_to tag,:controller => "tags",:action => "index",:q=>tag ,:object_flag => object_flag,:obj_id => obj.id %> +
    + <% end %> + <% end %> + +<% end %> \ No newline at end of file diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb new file mode 100644 index 000000000..8f23129b4 --- /dev/null +++ b/app/views/layouts/admin.html.erb @@ -0,0 +1,8 @@ +<% unless controller_name == 'admin' && action_name == 'index' %> + <% content_for :sidebar do %> +

    <%=l(:label_administration)%>

    + <%= render :partial => 'admin/menu' %> + <% end %> +<% end %> + +<%= render :file => "layouts/base" %> diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb new file mode 100644 index 000000000..5925253b8 --- /dev/null +++ b/app/views/layouts/base.html.erb @@ -0,0 +1,43 @@ + + + + +<%=h html_title %> + + +<%= 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 %> + +<%= yield :header_tags -%> + + +
    +
    +
    + +<%=render :partial => 'layouts/base_header'%> + +
    +
    + <%= render_flash_messages %> + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    +
    +
    +
    + + + + + +
    +
    +<%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base.html_old.erb b/app/views/layouts/base.html_old.erb new file mode 100644 index 000000000..90cf1e886 --- /dev/null +++ b/app/views/layouts/base.html_old.erb @@ -0,0 +1,80 @@ + + + + +<%=h html_title %> + + +<%= 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 %> + +<%= yield :header_tags -%> + + +
    +
    +
    +
    +
    + <%= render_menu :account_menu -%> +
    + <%= 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? -%> +
    + + + + +
    + + + + + +
    +
    +<%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_.html.erb b/app/views/layouts/base_.html.erb new file mode 100644 index 000000000..7798eda33 --- /dev/null +++ b/app/views/layouts/base_.html.erb @@ -0,0 +1,75 @@ + + + + +<%=h html_title %> + + +<%= 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 %> + +<%= yield :header_tags -%> + + +
    +
    +
    +
    +
    + <%= render_menu :account_menu -%> +
    + <%= content_tag('div', "#{l(:label_logged_as_new)}: #{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? -%> +
    +<% if display_main_menu?(@project) %> + +<% end %> + +
    + + + + + +
    +
    +<%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_bids.html.erb b/app/views/layouts/base_bids.html.erb new file mode 100644 index 000000000..f61d1d1c7 --- /dev/null +++ b/app/views/layouts/base_bids.html.erb @@ -0,0 +1,159 @@ + + + + + <%= h html_title %> + + + <%= 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 %> + + <%= yield :header_tags -%> + + +
    +
    +
    + + <%=render :partial => 'layouts/base_header'%> + +
    + +
    + <% if display_main_menu?(@bid) %> +
    + <%= render_menu :bid_menu %> +
    + <% end %> + <%= render_flash_messages %> + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    +
    +
    +
    +
    + + + + + +
    +
    + <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_old.html.erb b/app/views/layouts/base_old.html.erb new file mode 100644 index 000000000..32da883ff --- /dev/null +++ b/app/views/layouts/base_old.html.erb @@ -0,0 +1,156 @@ + + + + + <%= h html_title %> + + + <%= 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 %> + + <%= yield :header_tags -%> + + +
    +
    +
    +
    +
    + <%= render_menu :account_menu -%> +
    + <%= 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? -%> +
    + + + + + + + + + + +
    +
    + <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_projects.html.erb b/app/views/layouts/base_projects.html.erb new file mode 100644 index 000000000..ca7c2ddf5 --- /dev/null +++ b/app/views/layouts/base_projects.html.erb @@ -0,0 +1,135 @@ + + + + + <%= h html_title %> + + + <%= 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 %> + + <%= yield :header_tags -%> + + +
    +
    +
    + + <%=render :partial => 'layouts/base_header'%> + +
    + + + +
    +
    + <%= render_main_menu(@project) %> +
    + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    + <%= render_flash_messages %> +
    +
    + + + + + +
    +
    + <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_users.html.erb b/app/views/layouts/base_users.html.erb new file mode 100644 index 000000000..f9c4c8c2d --- /dev/null +++ b/app/views/layouts/base_users.html.erb @@ -0,0 +1,155 @@ + + + + + <%= h html_title %> + + + <%= 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 %> + + <%= yield :header_tags -%> + + +
    +
    +
    +
    +
    +
    + <%= render_menu :account_menu -%> +
    + <%= 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? -%> +
    + +
    + + + +
    +
    + <%= render_menu :user_menu %> +
    + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    + <%= render_flash_messages %> +
    +
    + + + + + +
    +
    + <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..b95dc8ac8 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,33 @@ + + + + + +<%= Redmine::WikiFormatting.to_html(Setting.text_formatting, Setting.emails_header).html_safe %> +<%= yield %> +
    +<%= Redmine::WikiFormatting.to_html(Setting.text_formatting, Setting.emails_footer).html_safe %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..4b8c0b4f5 --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1,4 @@ +<%= Setting.emails_header %> +<%= yield %> +-- +<%= Setting.emails_footer %> diff --git a/app/views/list/members.html.erb b/app/views/list/members.html.erb new file mode 100644 index 000000000..e7b367639 --- /dev/null +++ b/app/views/list/members.html.erb @@ -0,0 +1,8 @@ + + + Hello, Rails! + + +

    Hello from Rails!

    + + \ No newline at end of file diff --git a/app/views/mailer/_issue.html.erb b/app/views/mailer/_issue.html.erb new file mode 100644 index 000000000..3d851d442 --- /dev/null +++ b/app/views/mailer/_issue.html.erb @@ -0,0 +1,15 @@ +

    <%= link_to(h("#{issue.tracker.name} ##{issue.id}: #{issue.subject}"), issue_url) %>

    + +
      +
    • <%=l(:field_author)%>: <%=h issue.author %>
    • +
    • <%=l(:field_status)%>: <%=h issue.status %>
    • +
    • <%=l(:field_priority)%>: <%=h issue.priority %>
    • +
    • <%=l(:field_assigned_to)%>: <%=h issue.assigned_to %>
    • +
    • <%=l(:field_category)%>: <%=h issue.category %>
    • +
    • <%=l(:field_fixed_version)%>: <%=h issue.fixed_version %>
    • +<% issue.custom_field_values.each do |c| %> +
    • <%=h c.custom_field.name %>: <%=h show_value(c) %>
    • +<% end %> +
    + +<%= textilizable(issue, :description, :only_path => false) %> diff --git a/app/views/mailer/_issue.text.erb b/app/views/mailer/_issue.text.erb new file mode 100644 index 000000000..427b6a890 --- /dev/null +++ b/app/views/mailer/_issue.text.erb @@ -0,0 +1,13 @@ +<%= "#{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 --git a/app/views/mailer/account_activated.html.erb b/app/views/mailer/account_activated.html.erb new file mode 100644 index 000000000..cb8d8caa1 --- /dev/null +++ b/app/views/mailer/account_activated.html.erb @@ -0,0 +1,2 @@ +

    <%= l(:notice_account_activated) %>

    +

    <%= l(:label_login) %>: <%= link_to h(@login_url), @login_url %>

    diff --git a/app/views/mailer/account_activated.text.erb b/app/views/mailer/account_activated.text.erb new file mode 100644 index 000000000..4dac4fb80 --- /dev/null +++ b/app/views/mailer/account_activated.text.erb @@ -0,0 +1,2 @@ +<%= l(:notice_account_activated) %> +<%= l(:label_login) %>: <%= @login_url %> diff --git a/app/views/mailer/account_activation_request.html.erb b/app/views/mailer/account_activation_request.html.erb new file mode 100644 index 000000000..4450631b9 --- /dev/null +++ b/app/views/mailer/account_activation_request.html.erb @@ -0,0 +1,2 @@ +

    <%= l(:mail_body_account_activation_request, h(@user.login)) %>

    +

    <%= link_to h(@url), @url %>

    diff --git a/app/views/mailer/account_activation_request.text.erb b/app/views/mailer/account_activation_request.text.erb new file mode 100644 index 000000000..f431e22d3 --- /dev/null +++ b/app/views/mailer/account_activation_request.text.erb @@ -0,0 +1,2 @@ +<%= l(:mail_body_account_activation_request, @user.login) %> +<%= @url %> diff --git a/app/views/mailer/account_information.html.erb b/app/views/mailer/account_information.html.erb new file mode 100644 index 000000000..426aacee1 --- /dev/null +++ b/app/views/mailer/account_information.html.erb @@ -0,0 +1,11 @@ +<% if @user.auth_source %> +

    <%= l(:mail_body_account_information_external, h(@user.auth_source.name)) %>

    +<% else %> +

    <%= l(:mail_body_account_information) %>:

    +
      +
    • <%= l(:field_login) %>: <%=h @user.login %>
    • +
    • <%= l(:field_password) %>: <%=h @password %>
    • +
    +<% end %> + +

    <%= l(:label_login) %>: <%= link_to h(@login_url), @login_url %>

    diff --git a/app/views/mailer/account_information.text.erb b/app/views/mailer/account_information.text.erb new file mode 100644 index 000000000..0a02566d9 --- /dev/null +++ b/app/views/mailer/account_information.text.erb @@ -0,0 +1,6 @@ +<% if @user.auth_source %><%= l(:mail_body_account_information_external, @user.auth_source.name) %> +<% else %><%= l(:mail_body_account_information) %>: +* <%= l(:field_login) %>: <%= @user.login %> +* <%= l(:field_password) %>: <%= @password %> +<% end %> +<%= l(:label_login) %>: <%= @login_url %> diff --git a/app/views/mailer/attachments_added.html.erb b/app/views/mailer/attachments_added.html.erb new file mode 100644 index 000000000..11d1cf54c --- /dev/null +++ b/app/views/mailer/attachments_added.html.erb @@ -0,0 +1,5 @@ +<%= link_to h(@added_to), @added_to_url %>
    + +
      <% @attachments.each do |attachment | %> +
    • <%=h attachment.filename %>
    • +<% end %>
    diff --git a/app/views/mailer/attachments_added.text.erb b/app/views/mailer/attachments_added.text.erb new file mode 100644 index 000000000..28cb8285e --- /dev/null +++ b/app/views/mailer/attachments_added.text.erb @@ -0,0 +1,4 @@ +<%= @added_to %><% @attachments.each do |attachment | %> +- <%= attachment.filename %><% end %> + +<%= @added_to_url %> diff --git a/app/views/mailer/document_added.html.erb b/app/views/mailer/document_added.html.erb new file mode 100644 index 000000000..8606dd784 --- /dev/null +++ b/app/views/mailer/document_added.html.erb @@ -0,0 +1,3 @@ +<%= link_to(h(@document.title), @document_url) %> (<%=h @document.category.name %>)
    +
    +<%= textilizable(@document, :description, :only_path => false) %> diff --git a/app/views/mailer/document_added.text.erb b/app/views/mailer/document_added.text.erb new file mode 100644 index 000000000..a6a72829e --- /dev/null +++ b/app/views/mailer/document_added.text.erb @@ -0,0 +1,4 @@ +<%= @document.title %> (<%= @document.category.name %>) +<%= @document_url %> + +<%= @document.description %> diff --git a/app/views/mailer/issue_add.html.erb b/app/views/mailer/issue_add.html.erb new file mode 100644 index 000000000..fb4a2dab6 --- /dev/null +++ b/app/views/mailer/issue_add.html.erb @@ -0,0 +1,3 @@ +<%= l(:text_issue_added, :id => "##{@issue.id}", :author => h(@issue.author)) %> +
    +<%= render :partial => 'issue', :formats => [:html], :locals => { :issue => @issue, :issue_url => @issue_url } %> diff --git a/app/views/mailer/issue_add.text.erb b/app/views/mailer/issue_add.text.erb new file mode 100644 index 000000000..e990ff0d2 --- /dev/null +++ b/app/views/mailer/issue_add.text.erb @@ -0,0 +1,4 @@ +<%= l(:text_issue_added, :id => "##{@issue.id}", :author => @issue.author) %> + +---------------------------------------- +<%= render :partial => 'issue', :formats => [:text], :locals => { :issue => @issue, :issue_url => @issue_url } %> diff --git a/app/views/mailer/issue_edit.html.erb b/app/views/mailer/issue_edit.html.erb new file mode 100644 index 000000000..720cfea69 --- /dev/null +++ b/app/views/mailer/issue_edit.html.erb @@ -0,0 +1,11 @@ +<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => h(@journal.user)) %> + +
      +<% details_to_strings(@journal.details, false, :only_path => false).each do |string| %> +
    • <%= string %>
    • +<% end %> +
    + +<%= textilizable(@journal, :notes, :only_path => false) %> +
    +<%= render :partial => 'issue', :formats => [:html], :locals => { :issue => @issue, :issue_url => @issue_url } %> diff --git a/app/views/mailer/issue_edit.text.erb b/app/views/mailer/issue_edit.text.erb new file mode 100644 index 000000000..e0f10811b --- /dev/null +++ b/app/views/mailer/issue_edit.text.erb @@ -0,0 +1,12 @@ +<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => @journal.user) %> + +<% details_to_strings(@journal.details, true).each do |string| -%> +<%= string %> +<% end -%> + +<% if @journal.notes? -%> +<%= @journal.notes %> + +<% end -%> +---------------------------------------- +<%= render :partial => 'issue', :formats => [:text], :locals => { :issue => @issue, :issue_url => @issue_url } %> diff --git a/app/views/mailer/lost_password.html.erb b/app/views/mailer/lost_password.html.erb new file mode 100644 index 000000000..d740480ad --- /dev/null +++ b/app/views/mailer/lost_password.html.erb @@ -0,0 +1,4 @@ +

    <%= l(:mail_body_lost_password) %>
    +<%= link_to h(@url), @url %>

    + +

    <%= l(:field_login) %>: <%=h @token.user.login %>

    diff --git a/app/views/mailer/lost_password.text.erb b/app/views/mailer/lost_password.text.erb new file mode 100644 index 000000000..f5000ed7e --- /dev/null +++ b/app/views/mailer/lost_password.text.erb @@ -0,0 +1,4 @@ +<%= l(:mail_body_lost_password) %> +<%= @url %> + +<%= l(:field_login) %>: <%= @token.user.login %> diff --git a/app/views/mailer/message_posted.html.erb b/app/views/mailer/message_posted.html.erb new file mode 100644 index 000000000..f43a8cf0f --- /dev/null +++ b/app/views/mailer/message_posted.html.erb @@ -0,0 +1,4 @@ +

    <%=h @message.board.project.name %> - <%=h @message.board.name %>: <%= link_to(h(@message.subject), @message_url) %>

    +<%=h @message.author %> + +<%= textilizable(@message, :content, :only_path => false) %> diff --git a/app/views/mailer/message_posted.text.erb b/app/views/mailer/message_posted.text.erb new file mode 100644 index 000000000..ef6a3b3ae --- /dev/null +++ b/app/views/mailer/message_posted.text.erb @@ -0,0 +1,4 @@ +<%= @message_url %> +<%= @message.author %> + +<%= @message.content %> diff --git a/app/views/mailer/news_added.html.erb b/app/views/mailer/news_added.html.erb new file mode 100644 index 000000000..758ebccb8 --- /dev/null +++ b/app/views/mailer/news_added.html.erb @@ -0,0 +1,4 @@ +

    <%= link_to(h(@news.title), @news_url) %>

    +<%=h @news.author.name %> + +<%= textilizable(@news, :description, :only_path => false) %> diff --git a/app/views/mailer/news_added.text.erb b/app/views/mailer/news_added.text.erb new file mode 100644 index 000000000..c8ae3035f --- /dev/null +++ b/app/views/mailer/news_added.text.erb @@ -0,0 +1,5 @@ +<%= @news.title %> +<%= @news_url %> +<%= @news.author.name %> + +<%= @news.description %> diff --git a/app/views/mailer/news_comment_added.html.erb b/app/views/mailer/news_comment_added.html.erb new file mode 100644 index 000000000..ef2be0f65 --- /dev/null +++ b/app/views/mailer/news_comment_added.html.erb @@ -0,0 +1,5 @@ +

    <%= link_to(h(@news.title), @news_url) %>

    + +

    <%= l(:text_user_wrote, :value => h(@comment.author)) %>

    + +<%= textilizable @comment, :comments, :only_path => false %> diff --git a/app/views/mailer/news_comment_added.text.erb b/app/views/mailer/news_comment_added.text.erb new file mode 100644 index 000000000..aadbc37c0 --- /dev/null +++ b/app/views/mailer/news_comment_added.text.erb @@ -0,0 +1,6 @@ +<%= @news.title %> +<%= @news_url %> + +<%= l(:text_user_wrote, :value => @comment.author) %> + +<%= @comment.comments %> diff --git a/app/views/mailer/register.html.erb b/app/views/mailer/register.html.erb new file mode 100644 index 000000000..282deca90 --- /dev/null +++ b/app/views/mailer/register.html.erb @@ -0,0 +1,2 @@ +

    <%= l(:mail_body_register) %>
    +<%= link_to h(@url), @url %>

    diff --git a/app/views/mailer/register.text.erb b/app/views/mailer/register.text.erb new file mode 100644 index 000000000..102a15ee3 --- /dev/null +++ b/app/views/mailer/register.text.erb @@ -0,0 +1,2 @@ +<%= l(:mail_body_register) %> +<%= @url %> diff --git a/app/views/mailer/reminder.html.erb b/app/views/mailer/reminder.html.erb new file mode 100644 index 000000000..f011da3e8 --- /dev/null +++ b/app/views/mailer/reminder.html.erb @@ -0,0 +1,9 @@ +

    <%= l(:mail_body_reminder, :count => @issues.size, :days => @days) %>

    + +
      +<% @issues.each do |issue| -%> +
    • <%=h issue.project %> - <%=link_to(h("#{issue.tracker} ##{issue.id}"), :controller => 'issues', :action => 'show', :id => issue, :only_path => false)%>: <%=h issue.subject %>
    • +<% end -%> +
    + +

    <%= link_to l(:label_issue_view_all), @issues_url %>

    diff --git a/app/views/mailer/reminder.text.erb b/app/views/mailer/reminder.text.erb new file mode 100644 index 000000000..c9e27dc8d --- /dev/null +++ b/app/views/mailer/reminder.text.erb @@ -0,0 +1,7 @@ +<%= l(:mail_body_reminder, :count => @issues.size, :days => @days) %>: + +<% @issues.each do |issue| -%> +* <%= "#{issue.project} - #{issue.tracker} ##{issue.id}: #{issue.subject}" %> +<% end -%> + +<%= @issues_url %> diff --git a/app/views/mailer/test_email.html.erb b/app/views/mailer/test_email.html.erb new file mode 100644 index 000000000..1e81b3bfe --- /dev/null +++ b/app/views/mailer/test_email.html.erb @@ -0,0 +1,2 @@ +

    This is a test email sent by Redmine.
    +Redmine URL: <%= link_to h(@url), @url %>

    diff --git a/app/views/mailer/test_email.text.erb b/app/views/mailer/test_email.text.erb new file mode 100644 index 000000000..790d6ab22 --- /dev/null +++ b/app/views/mailer/test_email.text.erb @@ -0,0 +1,2 @@ +This is a test email sent by Redmine. +Redmine URL: <%= @url %> diff --git a/app/views/mailer/wiki_content_added.html.erb b/app/views/mailer/wiki_content_added.html.erb new file mode 100644 index 000000000..8c83f62c8 --- /dev/null +++ b/app/views/mailer/wiki_content_added.html.erb @@ -0,0 +1,3 @@ +

    <%= l(:mail_body_wiki_content_added, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url), + :author => h(@wiki_content.author)).html_safe %>
    +<%=h @wiki_content.comments %>

    diff --git a/app/views/mailer/wiki_content_added.text.erb b/app/views/mailer/wiki_content_added.text.erb new file mode 100644 index 000000000..5e8c77fd9 --- /dev/null +++ b/app/views/mailer/wiki_content_added.text.erb @@ -0,0 +1,5 @@ +<%= l(:mail_body_wiki_content_added, :id => h(@wiki_content.page.pretty_title), + :author => h(@wiki_content.author)) %> +<%= @wiki_content.comments %> + +<%= @wiki_content_url %> diff --git a/app/views/mailer/wiki_content_updated.html.erb b/app/views/mailer/wiki_content_updated.html.erb new file mode 100644 index 000000000..f1f3857bd --- /dev/null +++ b/app/views/mailer/wiki_content_updated.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:mail_body_wiki_content_updated, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url), + :author => h(@wiki_content.author)).html_safe %>
    +<%=h @wiki_content.comments %>

    + +

    <%= l(:label_view_diff) %>:
    +<%= link_to h(@wiki_diff_url), @wiki_diff_url %>

    diff --git a/app/views/mailer/wiki_content_updated.text.erb b/app/views/mailer/wiki_content_updated.text.erb new file mode 100644 index 000000000..4b3a97360 --- /dev/null +++ b/app/views/mailer/wiki_content_updated.text.erb @@ -0,0 +1,8 @@ +<%= l(:mail_body_wiki_content_updated, :id => h(@wiki_content.page.pretty_title), + :author => h(@wiki_content.author)) %> +<%= @wiki_content.comments %> + +<%= @wiki_content.page.pretty_title %>: +<%= @wiki_content_url %> +<%= l(:label_view_diff) %>: +<%= @wiki_diff_url %> diff --git a/app/views/members/autocomplete.js.erb b/app/views/members/autocomplete.js.erb new file mode 100644 index 000000000..ba98983d3 --- /dev/null +++ b/app/views/members/autocomplete.js.erb @@ -0,0 +1 @@ +$('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>'); diff --git a/app/views/members/create.js.erb b/app/views/members/create.js.erb new file mode 100644 index 000000000..11c468a76 --- /dev/null +++ b/app/views/members/create.js.erb @@ -0,0 +1,11 @@ +$('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); +hideOnLoad(); + +<% if @members.present? && @members.all? {|m| m.valid? } %> + <% @members.each do |member| %> + $("#member-<%= member.id %>").effect("highlight"); + <% end %> +<% else %> + <% errors = @members.collect {|m| m.errors.full_messages}.flatten.uniq.join(', ') %> + alert('<%= raw(escape_javascript(l(:notice_failed_to_save_members, :errors => errors))) %>'); +<% end %> diff --git a/app/views/members/destroy.js.erb b/app/views/members/destroy.js.erb new file mode 100644 index 000000000..17beff44c --- /dev/null +++ b/app/views/members/destroy.js.erb @@ -0,0 +1,2 @@ +$('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); +hideOnLoad(); diff --git a/app/views/members/index.api.rsb b/app/views/members/index.api.rsb new file mode 100644 index 000000000..dd591ea7c --- /dev/null +++ b/app/views/members/index.api.rsb @@ -0,0 +1,18 @@ +api.array :memberships, api_meta(:total_count => @member_count, :offset => @offset, :limit => @limit) do + @members.each do |membership| + api.membership do + api.id membership.id + api.project :id => membership.project.id, :name => membership.project.name + api.__send__ membership.principal.class.name.underscore, :id => membership.principal.id, :name => membership.principal.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 + end +end diff --git a/app/views/members/show.api.rsb b/app/views/members/show.api.rsb new file mode 100644 index 000000000..55def9eab --- /dev/null +++ b/app/views/members/show.api.rsb @@ -0,0 +1,14 @@ +api.membership do + api.id @member.id + api.project :id => @member.project.id, :name => @member.project.name + api.__send__ @member.principal.class.name.underscore, :id => @member.principal.id, :name => @member.principal.name + api.array :roles do + @member.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 diff --git a/app/views/members/update.js.erb b/app/views/members/update.js.erb new file mode 100644 index 000000000..245828aac --- /dev/null +++ b/app/views/members/update.js.erb @@ -0,0 +1,3 @@ +$('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); +hideOnLoad(); +$("#member-<%= @member.id %>").effect("highlight"); diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb new file mode 100644 index 000000000..d9f48af5c --- /dev/null +++ b/app/views/messages/_form.html.erb @@ -0,0 +1,32 @@ +<%= error_messages_for 'message' %> +<% replying ||= false %> + +
    + +


    +<%= f.text_field :subject, :size => 120, :id => "message_subject" %> + +<% unless replying %> + <% if @message.safe_attribute? 'sticky' %> + <%= f.check_box :sticky %> <%= label_tag 'message_sticky', l(:label_board_sticky) %> + <% end %> + <% if @message.safe_attribute? 'locked' %> + <%= f.check_box :locked %> <%= label_tag 'message_locked', l(:label_board_locked) %> + <% end %> +<% end %> +

    + +<% if !replying && !@message.new_record? && @message.safe_attribute?('board_id') %> +


    + <%= f.select :board_id, boards_options_for_select(@message.project.boards) %>

    +<% end %> + +

    +<%= 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' %>

    +<%= wikitoolbar_for 'message_content' %> + + +

    <%= l(:label_attachment_plural) %>
    +<%= render :partial => 'attachments/form', :locals => {:container => @message} %>

    +
    diff --git a/app/views/messages/edit.html.erb b/app/views/messages/edit.html.erb new file mode 100644 index 000000000..b7f591296 --- /dev/null +++ b/app/views/messages/edit.html.erb @@ -0,0 +1,17 @@ +<%= board_breadcrumb(@message) %> + +

    <%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %>

    + +<%= form_for @message, { + :as => :message, + :url => {:action => 'edit'}, + :html => {:multipart => true, + :id => 'message-form', + :method => :post} + } do |f| %> + <%= render :partial => 'form', + :locals => {:f => f, :replying => !@message.parent.nil?} %> + <%= submit_tag l(:button_save) %> + <%= preview_link({:controller => 'messages', :action => 'preview', :board_id => @board, :id => @message}, 'message-form') %> +<% end %> +
    diff --git a/app/views/messages/new.html.erb b/app/views/messages/new.html.erb new file mode 100644 index 000000000..f2137b989 --- /dev/null +++ b/app/views/messages/new.html.erb @@ -0,0 +1,9 @@ +

    <%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%= l(:label_message_new) %>

    + +<%= form_for @message, :url => {:action => 'new'}, :html => {:multipart => true, :id => 'message-form'} do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_create) %> + <%= preview_link({:controller => 'messages', :action => 'preview', :board_id => @board}, 'message-form') %> +<% end %> + +
    diff --git a/app/views/messages/quote.js.erb b/app/views/messages/quote.js.erb new file mode 100644 index 000000000..fe4bed91a --- /dev/null +++ b/app/views/messages/quote.js.erb @@ -0,0 +1,4 @@ +$('#message_subject').val("<%= raw escape_javascript(@subject) %>"); +$('#message_content').val("<%= raw escape_javascript(@content) %>"); +showAndScrollTo("reply", "message_content"); +$('#message_content').scrollTop = $('#message_content').scrollHeight - $('#message_content').clientHeight; diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb new file mode 100644 index 000000000..25ee3be08 --- /dev/null +++ b/app/views/messages/show.html.erb @@ -0,0 +1,86 @@ +<%= board_breadcrumb(@message) %> + +
    + <%= 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) %> +
    + +

    <%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %>

    + +
    +

    <%= authoring @topic.created_on, @topic.author %>

    +
    +<%= textilizable(@topic, :content) %> +
    +<%= link_to_attachments @topic, :author => false %> +
    +
    + +<% unless @replies.empty? %> +

    <%= l(:label_reply_plural) %> (<%= @reply_count %>)

    +<% @replies.each do |message| %> +
    "> +
    + <%= 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) %> +
    +

    + <%= 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 %> +

    +
    <%= textilizable message, :content, :attachments => message.attachments %>
    + <%= link_to_attachments message, :author => false %> +
    +<% end %> +

    <%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %>

    +<% end %> + +<% if !@topic.locked? && authorize_for('messages', 'reply') %> +

    <%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %>

    + +<% end %> + +<% html_title @topic.subject %> diff --git a/app/views/my/_block.html.erb b/app/views/my/_block.html.erb new file mode 100644 index 000000000..813eb2b88 --- /dev/null +++ b/app/views/my/_block.html.erb @@ -0,0 +1,10 @@ +
    + +
    + <%= link_to "", {:action => "remove_block", :block => block_name}, :method => 'post', :class => "close-icon" %> +
    + +
    + <%= render :partial => "my/blocks/#{block_name}", :locals => { :user => user } %> +
    +
    diff --git a/app/views/my/_sidebar.html.erb b/app/views/my/_sidebar.html.erb new file mode 100644 index 000000000..4c9270fc7 --- /dev/null +++ b/app/views/my/_sidebar.html.erb @@ -0,0 +1,36 @@ +

    <%=l(:label_my_account)%>

    + +

    <%=l(:field_login)%>: <%= link_to_user(@user, :format => :username) %>
    +<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %>

    + +<% if @user.own_account_deletable? %> +

    <%= link_to(l(:button_delete_my_account), {:action => 'destroy'}, :class => 'icon icon-del') %>

    +<% end %> + +

    <%= l(:label_feeds_access_key) %>

    + +

    +<% 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 %>) +

    + +<% if Setting.rest_api_enabled? %> +

    <%= l(:label_api_access_key) %>

    +
    + <%= link_to_function(l(:button_show), "$('#api-access-key').toggle();")%> +
    <%= h(@user.api_key) %>
    +
    +<%= javascript_tag("$('#api-access-key').hide();") %> +

    +<% 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 %>) +

    +<% end %> diff --git a/app/views/my/account.html.erb b/app/views/my/account.html.erb new file mode 100644 index 000000000..63ae8dc9e --- /dev/null +++ b/app/views/my/account.html.erb @@ -0,0 +1,75 @@ +
    + <%= 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)%> +
    + +

    <%= l(:label_my_account)%>

    + + +<%= labelled_form_for :user, @user, +:url => { :action => "account" }, +:html => { :id => 'my_account_form', +:method => :post } do |f| %> + +
    + + + <%= submit_tag l(:button_save) %> +
    +<% end %> +<%= error_messages_for 'user' %> +<% html_title(l(:label_my_account)) -%> diff --git a/app/views/my/blocks/_calendar.html.erb b/app/views/my/blocks/_calendar.html.erb new file mode 100644 index 000000000..41ca18a10 --- /dev/null +++ b/app/views/my/blocks/_calendar.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_calendar) %>

    + +<% 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 --git a/app/views/my/blocks/_documents.html.erb b/app/views/my/blocks/_documents.html.erb new file mode 100644 index 000000000..a55094cf1 --- /dev/null +++ b/app/views/my/blocks/_documents.html.erb @@ -0,0 +1,3 @@ +

    <%=l(:label_document_plural)%>

    + +<%= render :partial => 'documents/document', :collection => documents_items %> diff --git a/app/views/my/blocks/_issuesassignedtome.html.erb b/app/views/my/blocks/_issuesassignedtome.html.erb new file mode 100644 index 000000000..02d8c9aa6 --- /dev/null +++ b/app/views/my/blocks/_issuesassignedtome.html.erb @@ -0,0 +1,18 @@ +

    <%=l(:label_assigned_to_me_issues)%> (<%= Issue.visible.open.count(:conditions => {:assigned_to_id => ([User.current.id] + User.current.group_ids)})%>)

    + +<% assigned_issues = issuesassignedtome_items %> +<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %> +<% if assigned_issues.length > 0 %> +

    <%= link_to l(:label_issue_view_all), :controller => 'issues', + :action => 'index', + :set_filter => 1, + :assigned_to_id => 'me', + :sort => 'priority:desc,updated_on:desc' %>

    +<% 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 --git a/app/views/my/blocks/_issuesreportedbyme.html.erb b/app/views/my/blocks/_issuesreportedbyme.html.erb new file mode 100644 index 000000000..06bbda7f8 --- /dev/null +++ b/app/views/my/blocks/_issuesreportedbyme.html.erb @@ -0,0 +1,19 @@ +

    <%=l(:label_reported_issues)%> (<%= Issue.visible.count(:conditions => { :author_id => User.current.id }) %>)

    + +<% reported_issues = issuesreportedbyme_items %> +<%= render :partial => 'issues/list_simple', :locals => { :issues => reported_issues } %> +<% if reported_issues.length > 0 %> +

    <%= link_to l(:label_issue_view_all), :controller => 'issues', + :action => 'index', + :set_filter => 1, + :status_id => '*', + :author_id => 'me', + :sort => 'updated_on:desc' %>

    +<% 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 --git a/app/views/my/blocks/_issueswatched.html.erb b/app/views/my/blocks/_issueswatched.html.erb new file mode 100644 index 000000000..510920a08 --- /dev/null +++ b/app/views/my/blocks/_issueswatched.html.erb @@ -0,0 +1,11 @@ +

    <%=l(:label_watched_issues)%> (<%= Issue.visible.watched_by(user.id).count %>)

    +<% watched_issues = issueswatched_items %> + +<%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %> +<% if watched_issues.length > 0 %> +

    <%= link_to l(:label_issue_view_all), :controller => 'issues', + :action => 'index', + :set_filter => 1, + :watcher_id => 'me', + :sort => 'updated_on:desc' %>

    +<% end %> diff --git a/app/views/my/blocks/_news.html.erb b/app/views/my/blocks/_news.html.erb new file mode 100644 index 000000000..c478e4196 --- /dev/null +++ b/app/views/my/blocks/_news.html.erb @@ -0,0 +1,3 @@ +

    <%=l(:label_news_latest)%>

    + +<%= render :partial => 'news/news', :collection => news_items %> diff --git a/app/views/my/blocks/_timelog.html.erb b/app/views/my/blocks/_timelog.html.erb new file mode 100644 index 000000000..be8e05e35 --- /dev/null +++ b/app/views/my/blocks/_timelog.html.erb @@ -0,0 +1,49 @@ +

    <%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)

    +<% +entries = timelog_items +entries_by_day = entries.group_by(&:spent_on) +%> + +
    +

    <%= l(:label_total_time) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %>

    +
    + +<% if entries.any? %> + + + + + + + + + +<% entries_by_day.keys.sort.reverse.each do |day| %> + + + + + + + <% entries_by_day[day].each do |entry| -%> + + + + + + + + <% end -%> +<% end -%> + +
    <%= l(:label_activity) %><%= l(:label_project) %><%= l(:field_comments) %><%= l(:field_hours) %>
    <%= day == Date.today ? l(:label_today).titleize : format_date(day) %><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %>
    <%=h entry.activity %><%=h entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %><%=h entry.comments %><%= html_hours("%.2f" % entry.hours) %> + <% 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 -%> +
    +<% end %> diff --git a/app/views/my/destroy.html.erb b/app/views/my/destroy.html.erb new file mode 100644 index 000000000..96e21cf20 --- /dev/null +++ b/app/views/my/destroy.html.erb @@ -0,0 +1,11 @@ +

    <%=l(:label_confirmation)%>

    +
    +

    <%= simple_format l(:text_account_destroy_confirmation)%>

    +

    + <%= form_tag({}) do %> + + <%= submit_tag l(:button_delete_my_account) %> | + <%= link_to l(:button_cancel), :action => 'account' %> + <% end %> +

    +
    diff --git a/app/views/my/page.html.erb b/app/views/my/page.html.erb new file mode 100644 index 000000000..dd66f84a7 --- /dev/null +++ b/app/views/my/page.html.erb @@ -0,0 +1,36 @@ +
    + <%= link_to l(:label_personalize_page), :action => 'page_layout' %> +
    + +

    <%=l(:label_my_page)%>

    + +
    + <% @blocks['top'].each do |b| + next unless MyController::BLOCKS.keys.include? b %> +
    + <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> +
    + <% end if @blocks['top'] %> +
    + +
    + <% @blocks['left'].each do |b| + next unless MyController::BLOCKS.keys.include? b %> +
    + <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> +
    + <% end if @blocks['left'] %> +
    + +
    + <% @blocks['right'].each do |b| + next unless MyController::BLOCKS.keys.include? b %> +
    + <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> +
    + <% end if @blocks['right'] %> +
    + +<%= context_menu issues_context_menu_path %> + +<% html_title(l(:label_my_page)) -%> diff --git a/app/views/my/page_layout.html.erb b/app/views/my/page_layout.html.erb new file mode 100644 index 000000000..a1cdb2d10 --- /dev/null +++ b/app/views/my/page_layout.html.erb @@ -0,0 +1,41 @@ +
    +<% if @block_options.present? %> + <%= form_tag({:action => "add_block"}, :id => "block-form") do %> + <%= label_tag('block-select', l(:label_my_page_block)) %>: + <%= select_tag 'block', + content_tag('option') + options_for_select(@block_options), + :id => "block-select" %> + <%= link_to l(:button_add), '#', :onclick => '$("#block-form").submit()', :class => 'icon icon-add' %> + <% end %> +<% end %> +<%= link_to l(:button_back), {:action => 'page'}, :class => 'icon icon-cancel' %> +
    + +

    <%=l(:label_my_page)%>

    + +
    + <% @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'] %> +
    + +
    + <% @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'] %> +
    + +
    + <% @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'] %> +
    + +<%= javascript_tag "initMyPageSortable('top', '#{ escape_javascript url_for(:action => "order_blocks", :group => "top") }');" %> +<%= javascript_tag "initMyPageSortable('left', '#{ escape_javascript url_for(:action => "order_blocks", :group => "left") }');" %> +<%= javascript_tag "initMyPageSortable('right', '#{ escape_javascript url_for(:action => "order_blocks", :group => "right") }');" %> + +<% html_title(l(:label_my_page)) -%> diff --git a/app/views/my/password.html.erb b/app/views/my/password.html.erb new file mode 100644 index 000000000..5e2b1989c --- /dev/null +++ b/app/views/my/password.html.erb @@ -0,0 +1,23 @@ +

    <%=l(:button_change_password)%>

    + +<%= error_messages_for 'user' %> + +<%= form_tag({}, :class => "tabular") do %> +
    +

    +<%= password_field_tag 'password', nil, :size => 25 %>

    + +

    +<%= password_field_tag 'new_password', nil, :size => 25 %> +<%= l(:text_caracters_minimum, :count => Setting.password_min_length) %>

    + +

    +<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %>

    +<%= submit_tag l(:button_apply) %> +
    + +<% end %> + +<% content_for :sidebar do %> +<%= render :partial => 'sidebar' %> +<% end %> diff --git a/app/views/news/_form.html.erb b/app/views/news/_form.html.erb new file mode 100644 index 000000000..3f48d21de --- /dev/null +++ b/app/views/news/_form.html.erb @@ -0,0 +1,10 @@ +<%= error_messages_for @news %> + +
    +

    <%= f.text_field :title, :required => true, :size => 60 %>

    +

    <%= f.text_area :summary, :cols => 60, :rows => 2 %>

    +

    <%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit' %>

    +

    <%= render :partial => 'attachments/form', :locals => {:container => @news} %>

    +
    + +<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/news/_news.html.erb b/app/views/news/_news.html.erb new file mode 100644 index 000000000..001ad8179 --- /dev/null +++ b/app/views/news/_news.html.erb @@ -0,0 +1,27 @@ + + + + + + + + + + +
    + + + + + + + + + + +
    <%=link_to news.author,news_path(news)%> 分享了 <%= link_to h(news.title), news_path(news) %>

    <%=h news.description%>

    <%= news.created_on %><%= link_to"查看其他评论",news_path(news)%><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %>
    diff --git a/app/views/news/edit.html.erb b/app/views/news/edit.html.erb new file mode 100644 index 000000000..e5e5221b9 --- /dev/null +++ b/app/views/news/edit.html.erb @@ -0,0 +1,12 @@ +

    <%=l(:label_news)%>

    + +<%= labelled_form_for @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' %> +<% end %> +
    + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/news/index.api.rsb b/app/views/news/index.api.rsb new file mode 100644 index 000000000..5786cee3a --- /dev/null +++ b/app/views/news/index.api.rsb @@ -0,0 +1,14 @@ +api.array :news, api_meta(:total_count => @news_count, :offset => @offset, :limit => @limit) do + @newss.each do |news| + api.news do + api.id news.id + api.project(:id => news.project_id, :name => news.project.name) unless news.project.nil? + api.author(:id => news.author_id, :name => news.author.name) unless news.author.nil? + + api.title news.title + api.summary news.summary + api.description news.description + api.created_on news.created_on + end + end +end diff --git a/app/views/news/index.html.erb b/app/views/news/index.html.erb new file mode 100644 index 000000000..8381fb99d --- /dev/null +++ b/app/views/news/index.html.erb @@ -0,0 +1,78 @@ +
    +<%= link_to(l(:label_news_new), + new_project_news_path(@project), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') if @project && User.current.allowed_to?(:manage_news, @project) %> +
    + + + + + + +
    + + +<% if @newss.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> +<% @newss.each do |news| %> + + + + + +
    <%= link_to image_tag(url_to_avatar(@user), :class => 'avatar2'), :class => "avatar" %> + + + + + + + + + + +
    <%=link_to news.author%> 分享了 <%= link_to h(news.title), news_path(news) %>

    <%= textilizable(news, :description) %>

    <%= news.created_on %><%= link_to"查看其他评论",news_path(news)%><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %>
    +<% end %> +<% end %>
    + + + +
    +

    <%= pagination_links_full @news_pages %>

    + +<% 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 --git a/app/views/news/new.html.erb b/app/views/news/new.html.erb new file mode 100644 index 000000000..05a0afa6a --- /dev/null +++ b/app/views/news/new.html.erb @@ -0,0 +1,9 @@ +

    <%=l(:label_news_new)%>

    + +<%= labelled_form_for @news, :url => project_news_index_path(@project), + :html => { :id => 'news-form', :multipart => true } do |f| %> + <%= render :partial => 'news/form', :locals => { :f => f } %> + <%= submit_tag l(:button_create) %> + <%= preview_link preview_news_path(:project_id => @project), 'news-form' %> +<% end %> +
    diff --git a/app/views/news/show.html.erb b/app/views/news/show.html.erb new file mode 100644 index 000000000..a73447a86 --- /dev/null +++ b/app/views/news/show.html.erb @@ -0,0 +1,78 @@ +
    +<%= 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) %> +
    + +

    <%= link_to image_tag(url_to_avatar(@user), :class => 'avatar2'), :class => "avatar" %><%=h @news.title %>

    + +<% if authorize_for('news', 'edit') %> + +<% end %> + + + + + + + + +
    <%= link_to image_tag(url_to_avatar(@user), :class => 'avatar2'), :class => "avatar" %> + + + + + + + + + + +
    <%=link_to @news.author%> 分享了

    <% unless @news.summary.blank? %><%=h @news.summary %>
    <% end %>

    <%= textilizable(@news, :description) %>

    <%= @news.created_on %>dd
    + + + + + +
    +

    <%= l(:label_comment_plural) %>

    +<% @comments.each do |comment| %> + <% next if comment.new_record? %> +
    + <%= 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) %> +
    +

    <%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %>

    + <%= textilizable(comment.comments) %> +<% end if @comments.any? %> +
    + +<% if @news.commentable? %> +

    <%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %>

    +<%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %> +
    + <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'comment_comments' %> +
    +

    <%= submit_tag l(:button_add) %>

    +<% end %> +<% end %> + +<% html_title @news.title -%> + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/newsold/_form.html.erb b/app/views/newsold/_form.html.erb new file mode 100644 index 000000000..3f48d21de --- /dev/null +++ b/app/views/newsold/_form.html.erb @@ -0,0 +1,10 @@ +<%= error_messages_for @news %> + +
    +

    <%= f.text_field :title, :required => true, :size => 60 %>

    +

    <%= f.text_area :summary, :cols => 60, :rows => 2 %>

    +

    <%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit' %>

    +

    <%= render :partial => 'attachments/form', :locals => {:container => @news} %>

    +
    + +<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/newsold/_news.html.erb b/app/views/newsold/_news.html.erb new file mode 100644 index 000000000..ddbaecabf --- /dev/null +++ b/app/views/newsold/_news.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to_project(news.project) + ': ' unless @project %> +<%= link_to h(news.title), news_path(news) %> +<%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %> +
    +<% unless news.summary.blank? %><%=h news.summary %>
    <% end %> +<%= authoring news.created_on, news.author %>

    diff --git a/app/views/newsold/edit.html.erb b/app/views/newsold/edit.html.erb new file mode 100644 index 000000000..4e4cf2e2b --- /dev/null +++ b/app/views/newsold/edit.html.erb @@ -0,0 +1,12 @@ +

    <%=l(:label_news)%>

    + +<%= labelled_form_for @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' %> +<% end %> +
    + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/newsold/index.api.rsb b/app/views/newsold/index.api.rsb new file mode 100644 index 000000000..5786cee3a --- /dev/null +++ b/app/views/newsold/index.api.rsb @@ -0,0 +1,14 @@ +api.array :news, api_meta(:total_count => @news_count, :offset => @offset, :limit => @limit) do + @newss.each do |news| + api.news do + api.id news.id + api.project(:id => news.project_id, :name => news.project.name) unless news.project.nil? + api.author(:id => news.author_id, :name => news.author.name) unless news.author.nil? + + api.title news.title + api.summary news.summary + api.description news.description + api.created_on news.created_on + end + end +end diff --git a/app/views/newsold/index.html.erb b/app/views/newsold/index.html.erb new file mode 100644 index 000000000..38eecd262 --- /dev/null +++ b/app/views/newsold/index.html.erb @@ -0,0 +1,46 @@ +
    +<%= link_to(l(:label_news_new), + new_project_news_path(@project), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') if @project && User.current.allowed_to?(:manage_news, @project) %> +
    + + + +

    <%=l(:label_news_plural)%>

    + +<% if @newss.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> +<% @newss.each do |news| %> +

    <%= 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 %>

    +

    <%= authoring news.created_on, news.author %>

    +
    + <%= textilizable(news, :description) %> +
    +<% end %> +<% end %> +

    <%= pagination_links_full @news_pages %>

    + +<% 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 --git a/app/views/newsold/new.html.erb b/app/views/newsold/new.html.erb new file mode 100644 index 000000000..f96dd5c52 --- /dev/null +++ b/app/views/newsold/new.html.erb @@ -0,0 +1,9 @@ +

    <%=l(:label_news_new)%>

    + +<%= labelled_form_for @news, :url => project_news_index_path(@project), + :html => { :id => 'news-form', :multipart => true } do |f| %> + <%= render :partial => 'news/form', :locals => { :f => f } %> + <%= submit_tag l(:button_create) %> + <%= preview_link preview_news_path(:project_id => @project), 'news-form' %> +<% end %> +
    diff --git a/app/views/newsold/show.html.erb b/app/views/newsold/show.html.erb new file mode 100644 index 000000000..d359e90b9 --- /dev/null +++ b/app/views/newsold/show.html.erb @@ -0,0 +1,62 @@ +
    +<%= 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) %> +
    + +

    <%= avatar(@news.author, :size => "24") %><%=h @news.title %>

    + +<% if authorize_for('news', 'edit') %> + +<% end %> + +

    <% unless @news.summary.blank? %><%=h @news.summary %>
    <% end %> +<%= authoring @news.created_on, @news.author %>

    +
    +<%= textilizable(@news, :description) %> +
    +<%= link_to_attachments @news %> +
    + +
    +

    <%= l(:label_comment_plural) %>

    +<% @comments.each do |comment| %> + <% next if comment.new_record? %> +
    + <%= 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) %> +
    +

    <%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %>

    + <%= textilizable(comment.comments) %> +<% end if @comments.any? %> +
    + +<% if @news.commentable? %> +

    <%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %>

    +<%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %> +
    + <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'comment_comments' %> +
    +

    <%= submit_tag l(:button_add) %>

    +<% end %> +<% end %> + +<% html_title @news.title -%> + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/previews/issue.html.erb b/app/views/previews/issue.html.erb new file mode 100644 index 000000000..a88bec6fc --- /dev/null +++ b/app/views/previews/issue.html.erb @@ -0,0 +1,11 @@ +<% if @notes %> +
    <%= l(:field_notes) %> + <%= textilizable @notes, :attachments => @attachments, :object => @issue %> +
    +<% end %> + +<% if @description %> +
    <%= l(:field_description) %> + <%= textilizable @description, :attachments => @attachments, :object => @issue %> +
    +<% end %> diff --git a/app/views/projects/Copy of show.html.erb b/app/views/projects/Copy of show.html.erb new file mode 100644 index 000000000..7dfa9e705 --- /dev/null +++ b/app/views/projects/Copy of show.html.erb @@ -0,0 +1,53 @@ + + + +

    <%=link_to l(:label_news), project_news_index_path(@project) %>

    +
    + + <% if @news.any? && authorize_for('news', 'index') %> +
    + + <%= render :partial => 'news/news', :collection => @news %> +
    <%= link_to"更多",:contoller=>'project',:action=>'index'%>
    +
    + <% end %> + <%= call_hook(:view_projects_show_right, :project => @project) %> + +

    <%=link_to @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %>

    +
    + + +
    +<% @events_by_day.keys.sort.reverse.each do |day| %> + +
      +<% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%> + + +
    • + +
      <%= format_activity_day(day) %> + <%= format_time(e.event_datetime, false) %> + <%= 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 %> + + <%= link_to_user(e.event_author ,:class=>"author") if e.respond_to?(:event_author) %>
      +
    • <% end -%> +
    +<% end -%> +
    <%= link_to"更多",:contoller=>'project',:action=>'index'%>
    +
    + + diff --git a/app/views/projects/_edit.html.erb b/app/views/projects/_edit.html.erb new file mode 100644 index 000000000..211762903 --- /dev/null +++ b/app/views/projects/_edit.html.erb @@ -0,0 +1,4 @@ +<%= labelled_form_for @project do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/projects/_form.html.erb b/app/views/projects/_form.html.erb new file mode 100644 index 000000000..da5db62c3 --- /dev/null +++ b/app/views/projects/_form.html.erb @@ -0,0 +1,90 @@ +<%= error_messages_for 'project' %> + +
    + +

    <%= render :partial=>"avatar/avatar_form",:locals=> {source:@project}%>

    +

    <%= f.text_field :name, :required => true, :size => 60 %>

    + +

    <%= f.text_area :description, :rows => 8, :class => 'wiki-edit' %>

    +

    <%= f.text_field :identifier, :required => true, :size => 60, :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH %> +<% unless @project.identifier_frozen? %> + <%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %> +<% end %>

    +

    <%= f.text_field :homepage, :size => 60 %>

    +

    <%= f.check_box :is_public %>

    + +<% unless @project.allowed_parents.compact.empty? %> +

    <%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %>

    +<% end %> + +<% if @project.safe_attribute? 'inherit_members' %> +

    <%= f.check_box :inherit_members %>

    +<% end %> + +<%= wikitoolbar_for 'project_description' %> + +<% @project.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :project, value %>

    +<% end %> +<%= call_hook(:view_projects_form, :project => @project, :form => f) %> +
    + +<% if @project.new_record? %> +
    <%= l(:label_module_plural) %> +<% Redmine::AccessControl.available_project_modules.each do |m| %> + +<% end %> +<%= hidden_field_tag 'project[enabled_module_names][]', '' %> +<%= javascript_tag 'observeProjectModules()' %> +
    +<% end %> + +<% if @project.new_record? || @project.module_enabled?('issue_tracking') %> +<% unless @trackers.empty? %> +
    <%=l(:label_tracker_plural)%> +<% @trackers.each do |tracker| %> + +<% end %> +<%= hidden_field_tag 'project[tracker_ids][]', '' %> +
    +<% end %> + +<% unless @issue_custom_fields.empty? %> +
    <%=l(:label_custom_field_plural)%> +<% @issue_custom_fields.each do |custom_field| %> + +<% end %> +<%= hidden_field_tag 'project[issue_custom_field_ids][]', '' %> +
    +<% end %> +<% end %> + + +<% 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 --git a/app/views/projects/_members_box.html.erb b/app/views/projects/_members_box.html.erb new file mode 100644 index 000000000..4e3a1cb9f --- /dev/null +++ b/app/views/projects/_members_box.html.erb @@ -0,0 +1,8 @@ + <% if @users_by_role.any? %> +
    +

    <%=l(:label_member_plural)%>

    +

    <% @users_by_role.keys.sort.each do |role| %> + <%=h role %>: <%= @users_by_role[role].sort.collect{|u| link_to_user u}.join(", ").html_safe %>
    + <% end %>

    +
    + <% end %> diff --git a/app/views/projects/_project.html.erb b/app/views/projects/_project.html.erb new file mode 100644 index 000000000..2bd9c3330 --- /dev/null +++ b/app/views/projects/_project.html.erb @@ -0,0 +1,58 @@ +
    +
    + <%= tag('img', {:src => '../images/logo-only_med.png', :class => 'img_ta'}, false, false) %> +
    +
    +

    + Claimed by <%= content_tag('a', project.name) %> | Analyzed about 11 hours ago +

    +

    + <%= textilizable(project.short_description, :project => project) %> +

    +
    +
    +

    + <%= content_tag('a', @project.watcher_users.count) %><%= content_tag('span', l(:label_follow_people)) %> +

    +

    + <%= content_tag('a', "#{@project.users.count}") %><%= content_tag('span', l(:label_current_contributors)) %> +

    +

    + <%= content_tag('a', "#{(@project.repository.nil? || @project.repository.changesets[0].nil?) ? '0' : distance_of_time_in_words(Time.now, @project.repository.changesets[0].committed_on)}") %><%= content_tag('span', l(:label_since_last_commits)) %> +

    +

    + <%= content_tag('a', "#{@project.repository.nil? ? '0' : @project.repository.changesets.count }") %><%= content_tag('span', l(:label_commit_on)) %> +

    +
    + +
    +
    +
    + <%= content_tag('span', "#{l(:default_role_manager)}: ") %> + <% @admin = @project.users_by_role[Role.find(3)]%> + <% unless @admin.nil?%> + <%= content_tag('a', @admin.sort.collect{|u| link_to_user u}.join(", ").html_safe) %> + <% end %> +
    +
    + <%= content_tag('span', "#{l(:label_create_time)}: ") %><%= content_tag('span', format_time(@project.created_on)) %> +
    + + <% unless User.current.member_of?(@project) %> + <%= watcher_link(@project, User.current) %> + <% end %> + +
    +
    + +
    + <%= tag('img', {:src => "../images/user.png"}, false, false) %> + <%= render :partial => 'layouts/tag_name', :locals => {:obj => @project,:object_flag => "2",:non_list_all => true }%> + +
    +
    diff --git a/app/views/projects/copy.html.erb b/app/views/projects/copy.html.erb new file mode 100644 index 000000000..931853491 --- /dev/null +++ b/app/views/projects/copy.html.erb @@ -0,0 +1,20 @@ +

    <%=l(:label_project_new)%>

    + +<%= labelled_form_for @project, :url => { :action => "copy" } do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> + +
    <%= l(:button_copy) %> + + + + + + + + <%= hidden_field_tag 'only[]', '' %> +
    + +
    + +<%= submit_tag l(:button_copy) %> +<% end %> diff --git a/app/views/projects/destroy.html.erb b/app/views/projects/destroy.html.erb new file mode 100644 index 000000000..49d5babf7 --- /dev/null +++ b/app/views/projects/destroy.html.erb @@ -0,0 +1,17 @@ +

    <%=l(:label_confirmation)%>

    +
    +

    <%=h @project_to_destroy %>
    +<%=l(:text_project_destroy_confirmation)%> + +<% if @project_to_destroy.descendants.any? %> +
    <%= l(:text_subprojects_destroy_warning, + content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))).html_safe %> +<% end %> +

    +

    + <%= form_tag(project_path(@project_to_destroy), :method => :delete) do %> + + <%= submit_tag l(:button_delete) %> + <% end %> +

    +
    diff --git a/app/views/projects/file.html.erb b/app/views/projects/file.html.erb new file mode 100644 index 000000000..3ea345168 --- /dev/null +++ b/app/views/projects/file.html.erb @@ -0,0 +1 @@ +

    文件列表

    \ No newline at end of file diff --git a/app/views/projects/focus.html.erb b/app/views/projects/focus.html.erb new file mode 100644 index 000000000..e3f45a489 --- /dev/null +++ b/app/views/projects/focus.html.erb @@ -0,0 +1 @@ +

    关注列表

    \ No newline at end of file diff --git a/app/views/projects/index.api.rsb b/app/views/projects/index.api.rsb new file mode 100644 index 000000000..8fdea9bae --- /dev/null +++ b/app/views/projects/index.api.rsb @@ -0,0 +1,16 @@ +api.array :projects, api_meta(:total_count => @project_count, :offset => @offset, :limit => @limit) do + @projects.each do |project| + api.project do + api.id project.id + api.name project.name + api.identifier project.identifier + api.description project.description + api.parent(:id => project.parent.id, :name => project.parent.name) if project.parent && project.parent.visible? + + render_api_custom_values project.visible_custom_field_values, api + + api.created_on project.created_on + api.updated_on project.updated_on + end + end +end diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb new file mode 100644 index 000000000..0124f1f38 --- /dev/null +++ b/app/views/projects/index.html.erb @@ -0,0 +1,35 @@ +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> +<% end %> + +

    <%=l(:label_project_plural)%>

    + +
    +<%= render_project_hierarchy(@projects)%> +
    + + + +<% if User.current.logged? %> +

    +<%= l(:label_my_projects) %> +

    +<% end %> + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% content_for :sidebar do %> + <%= form_tag({}, :method => :get) do %> +

    <%= l(:label_project_plural) %>

    + +

    <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %>

    + <% end %> +<% end %> + +<% html_title(l(:label_project_plural)) -%> diff --git a/app/views/projects/investor.html.erb b/app/views/projects/investor.html.erb new file mode 100644 index 000000000..aa9d2ad67 --- /dev/null +++ b/app/views/projects/investor.html.erb @@ -0,0 +1 @@ +

    投资者列表

    \ No newline at end of file diff --git a/app/views/projects/issue.html.erb b/app/views/projects/issue.html.erb new file mode 100644 index 000000000..67e413510 --- /dev/null +++ b/app/views/projects/issue.html.erb @@ -0,0 +1 @@ +

    缺陷列表

    \ No newline at end of file diff --git a/app/views/projects/list_members.html.erb b/app/views/projects/list_members.html.erb new file mode 100644 index 000000000..715f689e7 --- /dev/null +++ b/app/views/projects/list_members.html.erb @@ -0,0 +1,13 @@ +

    <%=l(:label_member_plural)%>

    + +<% if @members.empty? %>

    <%= l(:label_no_data) %>

    <% end %> + +<% members = @members.group_by {|m| m.role } %> +<% members.keys.sort{|x,y| x.position <=> y.position}.each do |role| %> +

    <%= h(role.name) %>

    +
      +<% members[role].each do |m| %> +
    • <%= link_to_user m.user %> (<%= format_date m.created_on %>)
    • +<% end %> +
    +<% end %> diff --git a/app/views/projects/member.html.erb b/app/views/projects/member.html.erb new file mode 100644 index 000000000..2be9a2dac --- /dev/null +++ b/app/views/projects/member.html.erb @@ -0,0 +1,27 @@ + +

    <%= l(:label_member_list)%>

    +
    +<%= error_messages_for 'member' %> +<% roles = Role.find_all_givable + members = @project.member_principals.includes(:roles, :principal).all.sort %> +<% if members.any? %> +<% members.each do |member| %> +
    + + <% next if member.new_record? %> + <% unless member.created_on.nil? %> + <%= content_tag "p", "#{format_time(member.created_on)}#{l(:label_member_since)}", :class => "float_right member_since" %> + <% end %> + <%= member.user.nil? ? '' : (link_to image_tag(url_to_avatar(member.user), :class => 'avatar'), :class => "avatar") %> + <%= content_tag "div", link_to_user(member.principal), :class => "nomargin avatar_name" %> + <%= content_tag "div", content_tag("p", member.roles.sort.collect(&:to_s).join(', ')), :class => "clear avatar_name" %> + <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> + +
    +<% end; reset_cycle %> +<% else %> +

    + <%= l(:label_no_data) %> +

    + <% end %> +
    \ No newline at end of file diff --git a/app/views/projects/mission.html.erb b/app/views/projects/mission.html.erb new file mode 100644 index 000000000..1b996ec4c --- /dev/null +++ b/app/views/projects/mission.html.erb @@ -0,0 +1 @@ +

    任务列表

    \ No newline at end of file diff --git a/app/views/projects/new.html.erb b/app/views/projects/new.html.erb new file mode 100644 index 000000000..95b233f48 --- /dev/null +++ b/app/views/projects/new.html.erb @@ -0,0 +1,8 @@ +

    <%=l(:label_project_new)%>

    + +<%= labelled_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 "$('#project_name').focus();" %> +<% end %> diff --git a/app/views/projects/on.html.erb b/app/views/projects/on.html.erb new file mode 100644 index 000000000..d9dac658e --- /dev/null +++ b/app/views/projects/on.html.erb @@ -0,0 +1 @@ +

    æäº¤åˆ—表

    \ No newline at end of file diff --git a/app/views/projects/settings.html.erb b/app/views/projects/settings.html.erb new file mode 100644 index 000000000..ed8215ba4 --- /dev/null +++ b/app/views/projects/settings.html.erb @@ -0,0 +1,5 @@ +

    <%=l(:label_settings)%>

    + +<%= render_tabs project_settings_tabs %> + +<% html_title(l(:label_settings)) -%> diff --git a/app/views/projects/settings/_activities.html.erb b/app/views/projects/settings/_activities.html.erb new file mode 100644 index 000000000..8c9a6121c --- /dev/null +++ b/app/views/projects/settings/_activities.html.erb @@ -0,0 +1,42 @@ +<%= form_tag(project_enumerations_path(@project), :method => :put, :class => "tabular") do %> + + + + + + <% TimeEntryActivity.new.available_custom_fields.each do |value| %> + + <% end %> + + + + <% @project.activities(true).each do |enumeration| %> + <%= fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %> + + + + <% enumeration.custom_field_values.each do |value| %> + + <% end %> + + + <% end %> + <% end %> +
    <%= l(:field_name) %><%= l(:enumeration_system_activity) %><%= h value.name %><%= l(:field_active) %>
    + <%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %> + <%= h(enumeration) %> + <%= checked_image !enumeration.project %> + <%= custom_field_tag "enumerations[#{enumeration.id}]", value %> + + <%= ff.check_box :active %> +
    + +
    +<%= link_to(l(:button_reset), project_enumerations_path(@project), + :method => :delete, + :data => {:confirm => l(:text_are_you_sure)}, + :class => 'icon icon-del') %> +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/projects/settings/_boards.html.erb b/app/views/projects/settings/_boards.html.erb new file mode 100644 index 000000000..1050ef70c --- /dev/null +++ b/app/views/projects/settings/_boards.html.erb @@ -0,0 +1,36 @@ +<% if @project.boards.any? %> + + + + + + + + +<% Board.board_tree(@project.boards) do |board, level| + next if board.new_record? %> + + + + + + +<% end %> + +
    <%= l(:label_board) %><%= l(:field_description) %>
    <%= link_to board.name, project_board_path(@project, board) %><%=h board.description %> + <% if authorize_for("boards", "edit") %> + <%= reorder_links('board', {:controller => 'boards', :action => 'update', :project_id => @project, :id => board}, :put) %> + <% end %> + + <% if User.current.allowed_to?(:manage_boards, @project) %> + <%= link_to l(:button_edit), edit_project_board_path(@project, board), :class => 'icon icon-edit' %> + <%= delete_link project_board_path(@project, board) %> + <% end %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +<% if User.current.allowed_to?(:manage_boards, @project) %> +

    <%= link_to l(:label_board_new), new_project_board_path(@project), :class => 'icon icon-add' %>

    +<% end %> diff --git a/app/views/projects/settings/_issue_categories.html.erb b/app/views/projects/settings/_issue_categories.html.erb new file mode 100644 index 000000000..e88a85d50 --- /dev/null +++ b/app/views/projects/settings/_issue_categories.html.erb @@ -0,0 +1,29 @@ +<% if @project.issue_categories.any? %> + + + + + + + +<% for category in @project.issue_categories %> + <% unless category.new_record? %> + + + + + + <% end %> +<% end %> + +
    <%= l(:label_issue_category) %><%= l(:field_assigned_to) %>
    <%=h(category.name) %><%=h(category.assigned_to.name) if category.assigned_to %> + <% if User.current.allowed_to?(:manage_categories, @project) %> + <%= link_to l(:button_edit), edit_issue_category_path(category), :class => 'icon icon-edit' %> + <%= delete_link issue_category_path(category) %> + <% end %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +

    <%= 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) %>

    diff --git a/app/views/projects/settings/_members.html.erb b/app/views/projects/settings/_members.html.erb new file mode 100644 index 000000000..edd7a27f1 --- /dev/null +++ b/app/views/projects/settings/_members.html.erb @@ -0,0 +1,77 @@ +<%= error_messages_for 'member' %> +<% roles = Role.find_all_givable + members = @project.member_principals.includes(:roles, :principal).all.sort %> + +
    +<% if roles.any? %> + <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> +
    <%=l(:label_member_new)%> + +

    <%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %>

    + <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %> + +
    + <%= render_principals_for_new_members(@project) %> +
    + +

    <%= l(:label_role_plural) %>: + <% roles.each do |role| %> + + <% end %>

    + +

    <%= submit_tag l(:button_add), :id => 'member-add-submit' %>

    +
    + <% end %> +<% end %> +
    + +
    +<% if members.any? %> + + + + + + <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> + + + <% members.each do |member| %> + <% next if member.new_record? %> + + + + + <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> + +<% end; reset_cycle %> + +
    <%= l(:label_user) %> / <%= l(:label_group) %><%= l(:label_role_plural) %>
    <%= link_to_user member.principal %> + <%=h member.roles.sort.collect(&:to_s).join(', ') %> + <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member), + :method => :put, + :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }} + ) do |f| %> +

    <% roles.each do |role| %> +
    + <% end %>

    + <%= hidden_field_tag 'membership[role_ids][]', '' %> +

    <%= 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;" + %>

    + <% end %> +
    + <%= 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? %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> +
    + + diff --git a/app/views/projects/settings/_modules.html.erb b/app/views/projects/settings/_modules.html.erb new file mode 100644 index 000000000..d151a04b5 --- /dev/null +++ b/app/views/projects/settings/_modules.html.erb @@ -0,0 +1,18 @@ +<%= form_for @project, + :url => { :action => 'modules', :id => @project }, + :html => {:id => 'modules-form', + :method => :post} do |f| %> + +
    +<%= l(:text_select_project_modules) %> + +<% Redmine::AccessControl.available_project_modules.each do |m| %> +

    +<% end %> +
    +

    <%= check_all_links 'modules-form' %>

    + +

    <%= submit_tag l(:button_save) %>

    + +<% end %> diff --git a/app/views/projects/settings/_repositories.html.erb b/app/views/projects/settings/_repositories.html.erb new file mode 100644 index 000000000..4492165c9 --- /dev/null +++ b/app/views/projects/settings/_repositories.html.erb @@ -0,0 +1,41 @@ +<% if @project.repositories.any? %> + + + + + + + + + + + + <% @project.repositories.sort.each do |repository| %> + + + + + + + + <% end %> + +
    <%= l(:field_identifier) %><%= l(:field_repository_is_default) %><%= l(:label_scm) %><%= l(:label_repository) %>
    + <%= link_to repository.identifier, + {:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %> + <%= checked_image repository.is_default? %><%=h repository.scm_name %><%=h repository.url %> + <% if User.current.allowed_to?(:manage_repository, @project) %> + <%= link_to(l(:label_user_plural), committers_repository_path(repository), + :class => 'icon icon-user') %> + <%= link_to(l(:button_edit), edit_repository_path(repository), + :class => 'icon icon-edit') %> + <%= delete_link repository_path(repository) %> + <% end %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +<% if User.current.allowed_to?(:manage_repository, @project) %> +

    <%= link_to l(:label_repository_new), new_project_repository_path(@project), :class => 'icon icon-add' %>

    +<% end %> diff --git a/app/views/projects/settings/_versions.html.erb b/app/views/projects/settings/_versions.html.erb new file mode 100644 index 000000000..778803bf3 --- /dev/null +++ b/app/views/projects/settings/_versions.html.erb @@ -0,0 +1,41 @@ +<% if @project.shared_versions.any? %> + + + + + + + + + + + +<% for version in @project.shared_versions.sort %> + + + + + + + + + +<% end; reset_cycle %> + +
    <%= l(:label_version) %><%= l(:field_effective_date) %><%= l(:field_description) %><%= l(:field_status) %><%= l(:field_sharing) %><%= l(:label_wiki_page) %>
    <%= link_to_version version %><%= format_date(version.effective_date) %><%=h version.description %><%= l("version_status_#{version.status}") %><%= 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? %> + <% if version.project == @project && User.current.allowed_to?(:manage_versions, @project) %> + <%= link_to l(:button_edit), edit_version_path(version), :class => 'icon icon-edit' %> + <%= delete_link version_path(version) %> + <% end %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +
    +<% if @project.versions.any? %> + <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %> +<% end %> +
    + +

    <%= link_to l(:label_version_new), new_project_version_path(@project, :back_url => ''), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %>

    diff --git a/app/views/projects/settings/_wiki.html.erb b/app/views/projects/settings/_wiki.html.erb new file mode 100644 index 000000000..8374abb3d --- /dev/null +++ b/app/views/projects/settings/_wiki.html.erb @@ -0,0 +1,19 @@ +<%= labelled_form_for @wiki, + :as => :wiki, + :url => { :controller => 'wikis', :action => 'edit', :id => @project }, + :remote => true, :method => 'post' do |f| %> + +<%= error_messages_for 'wiki' %> + +
    +

    <%= f.text_field :start_page, :size => 60, :required => true %> +<%= l(:text_unallowed_characters) %>: , . / ? ; : |

    +
    + +
    +<%= link_to(l(:button_delete), {:controller => 'wikis', :action => 'destroy', :id => @project}, + :class => 'icon icon-del') if @wiki && !@wiki.new_record? %> +
    + +<%= submit_tag((@wiki.nil? || @wiki.new_record?) ? l(:button_create) : l(:button_save)) %> +<% end %> diff --git a/app/views/projects/show-old.html.erb b/app/views/projects/show-old.html.erb new file mode 100644 index 000000000..4c8ae87a4 --- /dev/null +++ b/app/views/projects/show-old.html.erb @@ -0,0 +1,97 @@ +
    + <% 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 %> +
    + +

    <%=l(:label_overview)%>

    + +<% unless @project.active? %> +

    <%= l(:text_project_closed) %>

    +<% end %> + +
    + <% if @project.description.present? %> +
    + <%= textilizable @project.description %> +
    + <% end %> +
      + <% unless @project.homepage.blank? %> +
    • <%=l(:field_homepage)%>: <%= link_to h(@project.homepage), @project.homepage %>
    • + <% end %> + <% if @subprojects.any? %> +
    • <%=l(:label_subproject_plural)%>: + <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %>
    • + <% end %> + <% @project.visible_custom_field_values.each do |custom_value| %> + <% if !custom_value.value.blank? %> +
    • <%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %>
    • + <% end %> + <% end %> +
    + + <% if User.current.allowed_to?(:view_issues, @project) %> +
    +

    <%=l(:label_issue_tracking)%>

    +
      + <% for tracker in @trackers %> +
    • <%= 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) %> +
    • + <% end %> +
    +

    + <%= 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 %> +

    +
    + <% end %> + <%= call_hook(:view_projects_show_left, :project => @project) %> +
    + +
    + <%= render :partial => 'members_box' %> + + <% if @news.any? && authorize_for('news', 'index') %> +
    +

    <%=l(:label_news_latest)%>

    + <%= render :partial => 'news/news', :collection => @news %> +

    <%= link_to l(:label_news_view_all), project_news_index_path(@project) %>

    +
    + <% end %> + <%= call_hook(:view_projects_show_right, :project => @project) %> +
    + +<% content_for :sidebar do %> + <% if @total_hours.present? %> +

    <%= l(:label_spent_time) %>

    +

    <%= l_hours(@total_hours) %>

    +

    + <% 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)) %>

    + <% 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)) -%> \ No newline at end of file diff --git a/app/views/projects/show.api.rsb b/app/views/projects/show.api.rsb new file mode 100644 index 000000000..a6f26f893 --- /dev/null +++ b/app/views/projects/show.api.rsb @@ -0,0 +1,25 @@ +api.project do + api.id @project.id + api.name @project.name + api.identifier @project.identifier + api.description @project.description + api.homepage @project.homepage + api.parent(:id => @project.parent.id, :name => @project.parent.name) if @project.parent && @project.parent.visible? + + render_api_custom_values @project.visible_custom_field_values, api + + api.created_on @project.created_on + api.updated_on @project.updated_on + + api.array :trackers do + @project.trackers.each do |tracker| + api.tracker(:id => tracker.id, :name => tracker.name) + end + end if include_in_api_response?('trackers') + + api.array :issue_categories do + @project.issue_categories.each do |category| + api.issue_category(:id => category.id, :name => category.name) + end + end if include_in_api_response?('issue_categories') +end diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb new file mode 100644 index 000000000..4d9a70b2f --- /dev/null +++ b/app/views/projects/show.html.erb @@ -0,0 +1,97 @@ + +
    +

    <%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %>

    +

    + <%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %> +

    +
    + <% @events_by_day.keys.sort.reverse.each do |day| %> +

    +
    + <% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%> +
    + + + + + +
    <%= image_tag(url_to_avatar(e.event_author), :class => "avatar")%> + + + + + + + + + + +
    <%= h(e.project) if @project.nil? || @project != e.project %> æœ‰äº†æœ€æ–°åŠ¨æ€ <%= link_to format_activity_title(e.event_title), e.event_url %>

    <%= format_activity_description(e.event_description) %>

    <%= format_activity_day(day) %> <%= format_time(e.event_datetime, false) %><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %>
    +
    + <% end -%> +
    + <% end -%> +
    +
    + + + + + + + diff --git a/app/views/projects/show_new.html.erb b/app/views/projects/show_new.html.erb new file mode 100644 index 000000000..8ab657b06 --- /dev/null +++ b/app/views/projects/show_new.html.erb @@ -0,0 +1,97 @@ +
    + <% 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 %> +
    + +

    <%=l(:label_overview)%>

    + +<% unless @project.active? %> +

    <%= l(:text_project_closed) %>

    +<% end %> + +
    + <% if @project.description.present? %> +
    + <%= textilizable @project.description %> +
    + <% end %> +
      + <% unless @project.homepage.blank? %> +
    • <%=l(:field_homepage)%>: <%= link_to h(@project.homepage), @project.homepage %>
    • + <% end %> + <% if @subprojects.any? %> +
    • <%=l(:label_subproject_plural)%>: + <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %>
    • + <% end %> + <% @project.visible_custom_field_values.each do |custom_value| %> + <% if !custom_value.value.blank? %> +
    • <%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %>
    • + <% end %> + <% end %> +
    + + <% if User.current.allowed_to?(:view_issues, @project) %> +
    +

    <%=l(:label_issue_tracking)%>

    +
      + <% for tracker in @trackers %> +
    • <%= 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) %> +
    • + <% end %> +
    +

    + <%= 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 %> +

    +
    + <% end %> + <%= call_hook(:view_projects_show_left, :project => @project) %> +
    + +
    + <%= render :partial => 'members_box' %> + + <% if @news.any? && authorize_for('news', 'index') %> +
    +

    <%=l(:label_news_latest)%>

    + <%= render :partial => 'news/news', :collection => @news %> +

    <%= link_to l(:label_news_view_all), project_news_index_path(@project) %>

    +
    + <% end %> + <%= call_hook(:view_projects_show_right, :project => @project) %> +
    + +<% content_for :sidebar do %> + <% if @total_hours.present? %> +

    <%= l(:label_spent_time) %>

    +

    <%= l_hours(@total_hours) %>

    +

    + <% 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)) %>

    + <% 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 --git a/app/views/queries/_columns.html.erb b/app/views/queries/_columns.html.erb new file mode 100644 index 000000000..0d624d989 --- /dev/null +++ b/app/views/queries/_columns.html.erb @@ -0,0 +1,34 @@ + + + + + + + +
    + <%= label_tag "available_columns", l(:description_available_columns) %> +
    + <%= 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);" %> +
    +
    + +
    + <%= label_tag "selected_columns", l(:description_selected_columns) %> +
    + <%= 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);" %> +
    +
    + +
    + +<% content_for :header_tags do %> +<%= javascript_include_tag 'select_list_move' %> +<% end %> diff --git a/app/views/queries/_filters.html.erb b/app/views/queries/_filters.html.erb new file mode 100644 index 000000000..795f8075f --- /dev/null +++ b/app/views/queries/_filters.html.erb @@ -0,0 +1,28 @@ +<%= javascript_tag do %> +var operatorLabels = <%= raw_json Query.operators_labels %>; +var operatorByType = <%= raw_json Query.operators_by_filter_type %>; +var availableFilters = <%= raw_json query.available_filters_as_json %>; +var labelDayPlural = <%= raw_json l(:label_day_plural) %>; +var allProjects = <%= raw query.all_projects_values.to_json %>; +$(document).ready(function(){ + initFilters(); + <% query.filters.each do |field, options| %> + addFilter("<%= field %>", <%= raw_json query.operator_for(field) %>, <%= raw_json query.values_for(field) %>); + <% end %> +}); +<% end %> + + + + + + +
    + +
    +
    +<%= label_tag('add_filter_select', l(:label_filter_add)) %> +<%= select_tag 'add_filter_select', filters_options_for_select(query), :name => nil %> +
    +<%= hidden_field_tag 'f[]', '' %> +<% include_calendar_headers_tags %> diff --git a/app/views/queries/_form.html.erb b/app/views/queries/_form.html.erb new file mode 100644 index 000000000..1070b4716 --- /dev/null +++ b/app/views/queries/_form.html.erb @@ -0,0 +1,55 @@ +<%= error_messages_for 'query' %> + +
    +
    +

    +<%= text_field 'query', 'name', :size => 80 %>

    + +<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %> +

    +<%= 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");}') %>

    +<% end %> + +

    +<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, + :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %>

    + +

    +<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns', + :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %>

    + +

    +<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %>

    + +

    +<%= available_block_columns_tags(@query) %>

    +
    + +
    <%= l(:label_filter_plural) %> +<%= render :partial => 'queries/filters', :locals => {:query => query}%> +
    + +
    <%= l(:label_sort) %> +<% 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) %> +
    +<% end %> +
    + +<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %> +<%= l(:field_column_names) %> +<%= render_query_columns_selection(query) %> +<% end %> + +
    diff --git a/app/views/queries/edit.html.erb b/app/views/queries/edit.html.erb new file mode 100644 index 000000000..422e95c43 --- /dev/null +++ b/app/views/queries/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_query) %>

    + +<%= 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 --git a/app/views/queries/index.api.rsb b/app/views/queries/index.api.rsb new file mode 100644 index 000000000..800b4964e --- /dev/null +++ b/app/views/queries/index.api.rsb @@ -0,0 +1,10 @@ +api.array :queries, api_meta(:total_count => @query_count, :offset => @offset, :limit => @limit) do + @queries.each do |query| + api.query do + api.id query.id + api.name query.name + api.is_public query.is_public + api.project_id query.project_id + end + end +end diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb new file mode 100644 index 000000000..573a9918f --- /dev/null +++ b/app/views/queries/index.html.erb @@ -0,0 +1,27 @@ +
    +<%= link_to_if_authorized l(:label_query_new), new_project_query_path(:project_id => @project), :class => 'icon icon-add' %> +
    + +

    <%= l(:label_query_plural) %>

    + +<% if @queries.empty? %> +

    <%=l(:label_no_data)%>

    +<% else %> + + <% @queries.each do |query| %> + + + + + <% end %> +
    + <%= link_to h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %> + + + <% if query.editable_by?(User.current) %> + <%= link_to l(:button_edit), edit_query_path(query), :class => 'icon icon-edit' %> + <%= delete_link query_path(query) %> + + <% end %> +
    +<% end %> diff --git a/app/views/queries/new.html.erb b/app/views/queries/new.html.erb new file mode 100644 index 000000000..4d03768dd --- /dev/null +++ b/app/views/queries/new.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_query_new) %>

    + +<%= form_tag(@project ? project_queries_path(@project) : queries_path, :onsubmit => 'selectAllOptions("selected_columns");') do %> + <%= render :partial => 'form', :locals => {:query => @query} %> + <%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/reports/_details.html.erb b/app/views/reports/_details.html.erb new file mode 100644 index 000000000..4a01c7333 --- /dev/null +++ b/app/views/reports/_details.html.erb @@ -0,0 +1,30 @@ +<% if @statuses.empty? or rows.empty? %> +

    <%=l(:label_no_data)%>

    +<% else %> +<% col_width = 70 / (@statuses.length+3) %> + + + +<% for status in @statuses %> + +<% end %> + + + + + +<% for row in rows %> +"> + + <% for status in @statuses %> + + <% end %> + + + + +<% end %> + +
    <%=h status.name %><%=l(:label_open_issues_plural)%><%=l(:label_closed_issues_plural)%><%=l(:label_total)%>
    <%= link_to h(row.name), aggregate_path(@project, field_name, row) %><%= aggregate_link data, { field_name => row.id, "status_id" => status.id }, aggregate_path(@project, field_name, row, :status_id => status.id) %><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %>
    +<% end + reset_cycle %> diff --git a/app/views/reports/_simple.html.erb b/app/views/reports/_simple.html.erb new file mode 100644 index 000000000..8ea18f16f --- /dev/null +++ b/app/views/reports/_simple.html.erb @@ -0,0 +1,23 @@ +<% if @statuses.empty? or rows.empty? %> +

    <%=l(:label_no_data)%>

    +<% else %> + + + + + + + + +<% for row in rows %> +"> + + + + + +<% end %> + +
    <%=l(:label_open_issues_plural)%><%=l(:label_closed_issues_plural)%><%=l(:label_total)%>
    <%= link_to h(row.name), aggregate_path(@project, field_name, row) %><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %>
    +<% end + reset_cycle %> diff --git a/app/views/reports/issue_report.html.erb b/app/views/reports/issue_report.html.erb new file mode 100644 index 000000000..771c1a68f --- /dev/null +++ b/app/views/reports/issue_report.html.erb @@ -0,0 +1,33 @@ +

    <%=l(:label_report_plural)%>

    + +
    +

    <%=l(:field_tracker)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'tracker') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %> +
    +

    <%=l(:field_priority)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'priority') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %> +
    +

    <%=l(:field_assigned_to)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'assigned_to') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_assigned_to, :field_name => "assigned_to_id", :rows => @assignees } %> +
    +

    <%=l(:field_author)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'author') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %> +
    +<%= call_hook(:view_reports_issue_report_split_content_left, :project => @project) %> +
    + +
    +

    <%=l(:field_version)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'version') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_version, :field_name => "fixed_version_id", :rows => @versions } %> +
    +<% if @project.children.any? %> +

    <%=l(:field_subproject)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'subproject') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_subproject, :field_name => "project_id", :rows => @subprojects } %> +
    +<% end %> +

    <%=l(:field_category)%>  <%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'category') %>

    +<%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %> +
    +<%= call_hook(:view_reports_issue_report_split_content_right, :project => @project) %> +
    + diff --git a/app/views/reports/issue_report_details.html.erb b/app/views/reports/issue_report_details.html.erb new file mode 100644 index 000000000..958fc3a9b --- /dev/null +++ b/app/views/reports/issue_report_details.html.erb @@ -0,0 +1,7 @@ +

    <%=l(:label_report_plural)%>

    + +

    <%=@report_title%>

    +<%= render :partial => 'details', :locals => { :data => @data, :field_name => @field, :rows => @rows } %> +
    +<%= link_to l(:button_back), project_issues_report_path(@project) %> + diff --git a/app/views/repositories/_breadcrumbs.html.erb b/app/views/repositories/_breadcrumbs.html.erb new file mode 100644 index 000000000..86fe28cb5 --- /dev/null +++ b/app/views/repositories/_breadcrumbs.html.erb @@ -0,0 +1,31 @@ +<%= link_to(@repository.identifier.present? ? h(@repository.identifier) : 'root', + :action => 'show', :id => @project, + :repository_id => @repository.identifier_param, + :path => nil, :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, :repository_id => @repository.identifier_param, + :path => to_path_param(link_path), :rev => @rev %> +<% end %> +<% if filename %> + / <%= link_to h(filename), + :action => 'changes', :id => @project, :repository_id => @repository.identifier_param, + :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 --git a/app/views/repositories/_dir_list.html.erb b/app/views/repositories/_dir_list.html.erb new file mode 100644 index 000000000..26ba05bb6 --- /dev/null +++ b/app/views/repositories/_dir_list.html.erb @@ -0,0 +1,19 @@ +
    + + + + + +<% if @repository.report_last_commit %> + + + + +<% end %> + + + +<%= render :partial => 'dir_list_content' %> + +
    <%= l(:field_name) %><%= l(:field_filesize) %><%= l(:label_revision) %><%= l(:label_age) %><%= l(:field_author) %><%= l(:field_comments) %>
    +
    diff --git a/app/views/repositories/_dir_list_content.html.erb b/app/views/repositories/_dir_list_content.html.erb new file mode 100644 index 000000000..e595a77dd --- /dev/null +++ b/app/views/repositories/_dir_list_content.html.erb @@ -0,0 +1,31 @@ +<% @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) %> + +"> +<% if entry.is_dir? %> +  +<% end %> +<%= link_to h(ent_name), + {:action => (entry.is_dir? ? 'show' : 'changes'), :id => @project, :repository_id => @repository.identifier_param, :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)}")%> + +<%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %> +<% if @repository.report_last_commit %> +<%= link_to_revision(entry.changeset, @repository) if entry.changeset %> +<%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %> +<%= entry.author %> +<%=h truncate(entry.changeset.comments, :length => 50) if entry.changeset %> +<% end %> + +<% end %> diff --git a/app/views/repositories/_form.html.erb b/app/views/repositories/_form.html.erb new file mode 100644 index 000000000..1554eb56f --- /dev/null +++ b/app/views/repositories/_form.html.erb @@ -0,0 +1,27 @@ +<%= error_messages_for 'repository' %> + +
    +

    +<%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %> +<% if @repository && ! @repository.class.scm_available %> + <%= l(:text_scm_command_not_available) %> +<% end %> +

    + +

    <%= f.check_box :is_default, :label => :field_repository_is_default %>

    +

    <%= f.text_field :identifier, :disabled => @repository.identifier_frozen? %> +<% unless @repository.identifier_frozen? %> + <%= l(:text_length_between, :min => 1, :max => Repository::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_repository_identifier_info).html_safe %> +<% end %>

    + +<% button_disabled = true %> +<% if @repository %> +<% button_disabled = ! @repository.class.scm_available %> +<%= repository_field_tags(f, @repository)%> +<% end %> +
    + +

    + <%= submit_tag(@repository.new_record? ? l(:button_create) : l(:button_save), :disabled => button_disabled) %> + <%= link_to l(:button_cancel), settings_project_path(@project, :tab => 'repositories') %> +

    diff --git a/app/views/repositories/_link_to_functions.html.erb b/app/views/repositories/_link_to_functions.html.erb new file mode 100644 index 000000000..f75a7ce5f --- /dev/null +++ b/app/views/repositories/_link_to_functions.html.erb @@ -0,0 +1,19 @@ +<% if @entry && @entry.kind == 'file' %> + +

    +<%= link_to_if action_name != 'changes', l(:label_history), {:action => 'changes', :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(@path), :rev => @rev } %> | +<% if @repository.supports_cat? %> + <%= link_to_if action_name != 'entry', l(:button_view), {:action => 'entry', :id => @project, :repository_id => @repository.identifier_param, :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, :repository_id => @repository.identifier_param, :path => to_path_param(@path), :rev => @rev } %> | +<% end %> +<%= link_to(l(:button_download), + {:action => 'raw', :id => @project, + :repository_id => @repository.identifier_param, + :path => to_path_param(@path), + :rev => @rev}) if @repository.supports_cat? %> +<%= "(#{number_to_human_size(@entry.size)})" if @entry.size %> +

    + +<% end %> diff --git a/app/views/repositories/_navigation.html.erb b/app/views/repositories/_navigation.html.erb new file mode 100644 index 000000000..a42daa8f5 --- /dev/null +++ b/app/views/repositories/_navigation.html.erb @@ -0,0 +1,34 @@ +<% content_for :header_tags do %> + <%= javascript_include_tag 'repository_navigation' %> +<% end %> + +<%= link_to l(:label_statistics), + {:action => 'stats', :id => @project, :repository_id => @repository.identifier_param}, + :class => 'icon icon-stats' if @repository.supports_all_revisions? %> + +<%= form_tag({:action => controller.action_name, + :id => @project, + :repository_id => @repository.identifier_param, + :path => to_path_param(@path), + :rev => nil}, + {:method => :get, :id => 'revision_selector'}) do -%> + + <% 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 -%> + + <% if @repository.supports_all_revisions? %> + | <%= l(:label_revision) %>: + <%= text_field_tag 'rev', @rev, :size => 8 %> + <% end %> +<% end -%> diff --git a/app/views/repositories/_related_issues.html.erb b/app/views/repositories/_related_issues.html.erb new file mode 100644 index 000000000..ee814c9f4 --- /dev/null +++ b/app/views/repositories/_related_issues.html.erb @@ -0,0 +1,40 @@ +<% manage_allowed = User.current.allowed_to?(:manage_related_issues, @repository.project) %> + + + +<%= javascript_tag "observeAutocompleteField('issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => 'all')}')" %> diff --git a/app/views/repositories/_revision_graph.html.erb b/app/views/repositories/_revision_graph.html.erb new file mode 100644 index 000000000..ebda63bac --- /dev/null +++ b/app/views/repositories/_revision_graph.html.erb @@ -0,0 +1,18 @@ +<%= javascript_tag do %> +function revisionGraphHandler(){ + drawRevisionGraph( + document.getElementById('holder'), + <%= commits.to_json.html_safe %>, + <%= space %> + ); +} +$(document).ready(revisionGraphHandler); +$(window).resize(revisionGraphHandler); +<% end %> + +
    + +<% content_for :header_tags do %> + <%= javascript_include_tag 'raphael' %> + <%= javascript_include_tag 'revision_graph' %> +<% end %> diff --git a/app/views/repositories/_revisions.html.erb b/app/views/repositories/_revisions.html.erb new file mode 100644 index 000000000..844c06500 --- /dev/null +++ b/app/views/repositories/_revisions.html.erb @@ -0,0 +1,51 @@ +<% show_revision_graph = ( @repository.supports_revision_graph? && path.blank? ) %> +<%= if show_revision_graph && revisions && revisions.any? + indexed_commits, graph_space = index_commits(revisions, @repository.branches) do |scmid| + url_for( + :controller => 'repositories', + :action => 'revision', + :id => project, + :repository_id => @repository.identifier_param, + :rev => scmid) + end + render :partial => 'revision_graph', + :locals => { + :commits => indexed_commits, + :space => graph_space + } +end %> +<%= form_tag( + {:controller => 'repositories', :action => 'diff', :id => project, + :repository_id => @repository.identifier_param, :path => to_path_param(path)}, + :method => :get + ) do %> + + + + + + + + + + +<% show_diff = revisions.size > 1 %> +<% line_num = 1 %> +<% revisions.each do |changeset| %> + +<% id_style = (show_revision_graph ? "padding-left:#{(graph_space + 1) * 20}px" : nil) %> +<%= content_tag(:td, :class => 'id', :style => id_style) do %> + <%= link_to_revision(changeset, @repository) %> +<% end %> + + + + + + +<% line_num += 1 %> +<% end %> + +
    #<%= l(:label_date) %><%= l(:field_author) %><%= l(:field_comments) %>
    <%= radio_button_tag('rev', changeset.identifier, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('#cbto-#{line_num+1}').attr('checked',true);") if show_diff && (line_num < revisions.size) %><%= radio_button_tag('rev_to', changeset.identifier, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('#cb-#{line_num}').attr('checked')) {$('#cb-#{line_num-1}').attr('checked',true);}") if show_diff && (line_num > 1) %><%= format_time(changeset.committed_on) %><%= h truncate(changeset.author.to_s, :length => 30) %><%= textilizable(truncate_at_line_break(changeset.comments)) %>
    +<%= submit_tag(l(:label_view_diff), :name => nil) if show_diff %> +<% end %> diff --git a/app/views/repositories/add_related_issue.js.erb b/app/views/repositories/add_related_issue.js.erb new file mode 100644 index 000000000..f3864d3be --- /dev/null +++ b/app/views/repositories/add_related_issue.js.erb @@ -0,0 +1,7 @@ +<% if @issue %> + $('#related-issues').html('<%= escape_javascript(render :partial => "related_issues") %>'); + $('#related-issue-<%= @issue.id %>').effect("highlight"); + $('#issue_id').focus(); +<% else %> + alert("<%= raw(escape_javascript(l(:label_issue) + ' ' + l('activerecord.errors.messages.invalid'))) %>"); +<% end %> diff --git a/app/views/repositories/annotate.html.erb b/app/views/repositories/annotate.html.erb new file mode 100644 index 000000000..7658cd178 --- /dev/null +++ b/app/views/repositories/annotate.html.erb @@ -0,0 +1,36 @@ +<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> + +
    + <%= render :partial => 'navigation' %> +
    + +

    <%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %>

    + +<%= render :partial => 'link_to_functions' %> + +<% colors = Hash.new {|k,v| k[v] = (k.size % 12) } %> + +
    + + + <% line_num = 1; previous_revision = nil %> + <% syntax_highlight_lines(@path, Redmine::CodesetUtil.to_utf8_by_setting(@annotate.content)).each do |line| %> + <% revision = @annotate.revisions[line_num - 1] %> + + + + + + + <% line_num += 1; previous_revision = revision %> + <% end %> + +
    <%= line_num %> + <%= (revision.identifier ? link_to_revision(revision, @repository) : format_revision(revision)) if revision && revision != previous_revision %><%= h(revision.author.to_s.split('<').first) if revision && revision != previous_revision %>
    <%= line.html_safe %>
    +
    + +<% html_title(l(:button_annotate)) -%> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/repositories/changes.html.erb b/app/views/repositories/changes.html.erb new file mode 100644 index 000000000..9d7c4aa30 --- /dev/null +++ b/app/views/repositories/changes.html.erb @@ -0,0 +1,20 @@ +<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> + +
    + <%= render :partial => 'navigation' %> +
    + +

    <%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %>

    + +<%= render :partial => 'link_to_functions' %> + +<%= render_properties(@properties) %> + +<%= render(:partial => 'revisions', + :locals => {:project => @project, :path => @path, :revisions => @changesets, :entry => @entry }) unless @changesets.empty? %> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag "scm" %> +<% end %> + +<% html_title(l(:label_change_plural)) -%> diff --git a/app/views/repositories/committers.html.erb b/app/views/repositories/committers.html.erb new file mode 100644 index 000000000..ccb037e09 --- /dev/null +++ b/app/views/repositories/committers.html.erb @@ -0,0 +1,42 @@ +

    <%= l(:label_repository) %>

    + +<%= simple_format(l(:text_repository_usernames_mapping)) %> + +<% if @committers.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> + +<%= form_tag({}) do %> + + + + + + + + +<% i = 0 -%> +<% @committers.each do |committer, user_id| -%> + + + + + <% i += 1 -%> +<% end -%> + +
    <%= l(:field_login) %><%= l(:label_user) %>
    <%=h committer %> + <%= 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 + ) %> +
    +

    <%= submit_tag(l(:button_update)) %>

    +<% end %> + +<% end %> diff --git a/app/views/repositories/diff.html.erb b/app/views/repositories/diff.html.erb new file mode 100644 index 000000000..9416e551c --- /dev/null +++ b/app/views/repositories/diff.html.erb @@ -0,0 +1,27 @@ +

    <%= l(:label_revision) %> <%= @diff_format_revisions %> <%=h @path %>

    + + +<%= form_tag({:action => 'diff', :id => @project, + :repository_id => @repository.identifier_param, + :path => to_path_param(@path), :rev=> @rev}, :method => 'get') do %> + <%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %> +

    + <%= l(:label_view_diff) %>: + + +

    +<% end %> + +<% cache(@cache_key) do -%> +<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type, :diff_style => @repository.class.scm_name} %> +<% 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 --git a/app/views/repositories/edit.html.erb b/app/views/repositories/edit.html.erb new file mode 100644 index 000000000..f0eafcf39 --- /dev/null +++ b/app/views/repositories/edit.html.erb @@ -0,0 +1,5 @@ +

    <%= l(:label_repository) %>

    + +<%= labelled_form_for :repository, @repository, :url => repository_path(@repository), :html => {:method => :put, :id => 'repository-form'} do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> +<% end %> diff --git a/app/views/repositories/entry.html.erb b/app/views/repositories/entry.html.erb new file mode 100644 index 000000000..5aea99dcc --- /dev/null +++ b/app/views/repositories/entry.html.erb @@ -0,0 +1,15 @@ +<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> + +
    + <%= render :partial => 'navigation' %> +
    + +

    <%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %>

    + +<%= render :partial => 'link_to_functions' %> + +<%= render :partial => 'common/file', :locals => {:filename => @path, :content => @content} %> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag "scm" %> +<% end %> diff --git a/app/views/repositories/new.html.erb b/app/views/repositories/new.html.erb new file mode 100644 index 000000000..fae1e3b92 --- /dev/null +++ b/app/views/repositories/new.html.erb @@ -0,0 +1,5 @@ +

    <%= l(:label_repository_new) %>

    + +<%= labelled_form_for :repository, @repository, :url => project_repositories_path(@project), :html => {:id => 'repository-form'} do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> +<% end %> diff --git a/app/views/repositories/new.js.erb b/app/views/repositories/new.js.erb new file mode 100644 index 000000000..00fd9cf8a --- /dev/null +++ b/app/views/repositories/new.js.erb @@ -0,0 +1 @@ +$('#content').html('<%= escape_javascript(render :template => 'repositories/new', :formats => [:html]) %>'); diff --git a/app/views/repositories/remove_related_issue.js.erb b/app/views/repositories/remove_related_issue.js.erb new file mode 100644 index 000000000..c4dc0e974 --- /dev/null +++ b/app/views/repositories/remove_related_issue.js.erb @@ -0,0 +1 @@ +$('#related-issue-<%= @issue.id %>').remove(); diff --git a/app/views/repositories/revision.html.erb b/app/views/repositories/revision.html.erb new file mode 100644 index 000000000..0de0cfee7 --- /dev/null +++ b/app/views/repositories/revision.html.erb @@ -0,0 +1,97 @@ +
    + « + <% unless @changeset.previous.nil? -%> + <%= link_to_revision(@changeset.previous, @repository, :text => l(:label_previous)) %> + <% else -%> + <%= l(:label_previous) %> + <% end -%> +| + <% unless @changeset.next.nil? -%> + <%= link_to_revision(@changeset.next, @repository, :text => l(:label_next)) %> + <% else -%> + <%= l(:label_next) %> + <% end -%> + »  + + <%= form_tag({:controller => 'repositories', + :action => 'revision', + :id => @project, + :repository_id => @repository.identifier_param, + :rev => nil}, + :method => :get) do %> + <%= text_field_tag 'rev', @rev, :size => 8 %> + <%= submit_tag 'OK', :name => nil %> + <% end %> +
    + +

    <%= avatar(@changeset.user, :size => "24") %><%= l(:label_revision) %> <%= format_revision(@changeset) %>

    + +<% if @changeset.scmid.present? || @changeset.parents.present? || @changeset.children.present? %> + + <% if @changeset.scmid.present? %> + + + + <% end %> + <% if @changeset.parents.present? %> + + + + + <% end %> + <% if @changeset.children.present? %> + + + + + <% end %> +
    ID<%= h(@changeset.scmid) %>
    <%= l(:label_parent_revision) %> + <%= @changeset.parents.collect{ + |p| link_to_revision(p, @repository, :text => format_revision(p)) + }.join(", ").html_safe %> +
    <%= l(:label_child_revision) %> + <%= @changeset.children.collect{ + |p| link_to_revision(p, @repository, :text => format_revision(p)) + }.join(", ").html_safe %> +
    +<% end %> + +

    + +<%= authoring(@changeset.committed_on, @changeset.author) %> + +

    + +<%= textilizable @changeset.comments %> + +<% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %> + <%= render :partial => 'related_issues' %> +<% end %> + +<% if User.current.allowed_to?(:browse_repository, @project) %> +

    <%= l(:label_attachment_plural) %>

    +
      +
    • <%= l(:label_added) %>
    • +
    • <%= l(:label_modified) %>
    • +
    • <%= l(:label_copied) %>
    • +
    • <%= l(:label_renamed) %>
    • +
    • <%= l(:label_deleted) %>
    • +
    + +

    <%= link_to(l(:label_view_diff), + :action => 'diff', + :id => @project, + :repository_id => @repository.identifier_param, + :path => "", + :rev => @changeset.identifier) if @changeset.filechanges.any? %>

    + +
    +<%= render_changeset_changes %> +
    +<% end %> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag "scm" %> +<% end %> + +<% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%> diff --git a/app/views/repositories/revisions.html.erb b/app/views/repositories/revisions.html.erb new file mode 100644 index 000000000..7a7338099 --- /dev/null +++ b/app/views/repositories/revisions.html.erb @@ -0,0 +1,34 @@ +
    +<%= form_tag( + {:controller => 'repositories', :action => 'revision', :id => @project, + :repository_id => @repository.identifier_param}, + :method => :get + ) do %> + <%= l(:label_revision) %>: <%= text_field_tag 'rev', nil, :size => 8 %> + <%= submit_tag 'OK' %> +<% end %> +
    + +

    <%= l(:label_revision_plural) %>

    + +<%= render :partial => 'revisions', + :locals => {:project => @project, + :path => '', + :revisions => @changesets, + :entry => nil } %> + +

    <%= pagination_links_full @changeset_pages,@changeset_count %>

    + +<% 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 --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb new file mode 100644 index 000000000..35e6dadcb --- /dev/null +++ b/app/views/repositories/show.html.erb @@ -0,0 +1,77 @@ +<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> + +
    + <%= render :partial => 'navigation' %> +
    + +

    <%= render :partial => 'breadcrumbs', + :locals => { :path => @path, :kind => 'dir', :revision => @rev } %>

    + +<% if !@entries.nil? && authorize_for('repositories', 'browse') %> + <%= render :partial => 'dir_list' %> +<% end %> + +<%= render_properties(@properties) %> + +<% if authorize_for('repositories', 'revisions') %> + <% if @changesets && !@changesets.empty? %> +

    <%= l(:label_latest_revision_plural) %>

    + <%= render :partial => 'revisions', + :locals => {:project => @project, :path => @path, + :revisions => @changesets, :entry => nil }%> + <% end %> +

    + <% 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, + :repository_id => @repository.identifier_param %> + <% 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, + :repository_id => @repository.identifier_param, + :rev => @rev %> + <% end %> +

    + <% if @repository.supports_all_revisions? %> + <% 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, + :repository_id => @repository.identifier_param, + :key => User.current.rss_key} %> + <% end %> + <% end %> +<% end %> + +<% if @repositories.size > 1 %> + <% content_for :sidebar do %> +

    <%= l(:label_repository_plural) %>

    +

    + <%= @repositories.sort.collect {|repo| + link_to h(repo.name), + {:controller => 'repositories', :action => 'show', + :id => @project, :repository_id => repo.identifier_param, :rev => nil, :path => nil}, + :class => 'repository' + (repo == @repository ? ' selected' : '') + }.join('
    ').html_safe %> +

    + <% end %> +<% end %> + +<% content_for :header_tags do %> + <%= stylesheet_link_tag "scm" %> +<% end %> + +<% html_title(l(:label_repository)) -%> diff --git a/app/views/repositories/stats.html.erb b/app/views/repositories/stats.html.erb new file mode 100644 index 000000000..50648f66f --- /dev/null +++ b/app/views/repositories/stats.html.erb @@ -0,0 +1,12 @@ +

    <%= l(:label_statistics) %>

    + +

    +<%= tag("embed", :width => 670, :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :repository_id => @repository.identifier_param, :graph => "commits_per_month")) %> +

    +

    +<%= tag("embed", :width => 670, :height => 400, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :repository_id => @repository.identifier_param, :graph => "commits_per_author")) %> +

    + +

    <%= link_to l(:button_back), :action => 'show', :id => @project %>

    + +<% html_title(l(:label_repository), l(:label_statistics)) -%> diff --git a/app/views/roles/_form.html.erb b/app/views/roles/_form.html.erb new file mode 100644 index 000000000..d028c2f1c --- /dev/null +++ b/app/views/roles/_form.html.erb @@ -0,0 +1,32 @@ +<%= error_messages_for 'role' %> + +<% unless @role.anonymous? %> +
    +<% unless @role.builtin? %> +

    <%= f.text_field :name, :required => true %>

    +

    <%= f.check_box :assignable %>

    +<% end %> +

    <%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %>

    +<% if @role.new_record? && @roles.any? %> +

    +<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@roles, :id, :name, params[:copy_workflow_from] || @copy_from.try(:id))) %>

    +<% end %> +
    +<% end %> + +

    <%= l(:label_permissions) %>

    +
    +<% perms_by_module = @role.setable_permissions.group_by {|p| p.project_module.to_s} %> +<% perms_by_module.keys.sort.each do |mod| %> +
    <%= mod.blank? ? l(:label_project) : l_or_humanize(mod, :prefix => 'project_module_') %> + <% perms_by_module[mod].each do |permission| %> + + <% end %> +
    +<% end %> +
    <%= check_all_links 'permissions' %> +<%= hidden_field_tag 'role[permissions][]', '' %> +
    diff --git a/app/views/roles/edit.html.erb b/app/views/roles/edit.html.erb new file mode 100644 index 000000000..a932a169f --- /dev/null +++ b/app/views/roles/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to l(:label_role_plural), roles_path %> » <%=h @role.name %>

    + +<%= labelled_form_for @role do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/roles/index.api.rsb b/app/views/roles/index.api.rsb new file mode 100644 index 000000000..56adc767e --- /dev/null +++ b/app/views/roles/index.api.rsb @@ -0,0 +1,8 @@ +api.array :roles do + @roles.each do |role| + api.role do + api.id role.id + api.name role.name + end + end +end diff --git a/app/views/roles/index.html.erb b/app/views/roles/index.html.erb new file mode 100644 index 000000000..6b35200cd --- /dev/null +++ b/app/views/roles/index.html.erb @@ -0,0 +1,34 @@ +
    +<%= 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' %> +
    + +

    <%=l(:label_role_plural)%>

    + + + + + + + + +<% for role in @roles %> + "> + + + + +<% end %> + +
    <%=l(:label_role)%><%=l(:button_sort)%>
    <%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %> + <% unless role.builtin? %> + <%= reorder_links('role', {:action => 'update', :id => role}, :put) %> + <% end %> + + <%= link_to l(:button_copy), new_role_path(:copy => role), :class => 'icon icon-copy' %> + <%= delete_link role_path(role) unless role.builtin? %> +
    + +

    <%= pagination_links_full @role_pages %>

    + +<% html_title(l(:label_role_plural)) -%> diff --git a/app/views/roles/new.html.erb b/app/views/roles/new.html.erb new file mode 100644 index 000000000..d597bc094 --- /dev/null +++ b/app/views/roles/new.html.erb @@ -0,0 +1,6 @@ +

    <%= link_to l(:label_role_plural), roles_path %> » <%=l(:label_role_new)%>

    + +<%= labelled_form_for @role do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/roles/permissions.html.erb b/app/views/roles/permissions.html.erb new file mode 100644 index 000000000..1942092cd --- /dev/null +++ b/app/views/roles/permissions.html.erb @@ -0,0 +1,55 @@ +

    <%= link_to l(:label_role_plural), roles_path %> » <%=l(:label_permissions_report)%>

    + +<%= form_tag(permissions_roles_path, :id => 'permissions_form') do %> +<%= hidden_field_tag 'permissions[0]', '', :id => nil %> +
    + + + + + <% @roles.each do |role| %> + + <% end %> + + + +<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %> +<% perms_by_module.keys.sort.each do |mod| %> + <% unless mod.blank? %> + + + <% @roles.each do |role| %> + + <% end %> + + <% end %> + <% perms_by_module[mod].each do |permission| %> + + + <% @roles.each do |role| %> + + <% end %> + + <% end %> +<% end %> + +
    <%=l(:label_permissions)%> + <%= 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)}") %> +
    +   + <%= l_or_humanize(mod, :prefix => 'project_module_') %> + <%= h(role.name) %>
    + <%= 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_') %> + + <% 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 %> +
    +
    +

    <%= check_all_links 'permissions_form' %>

    +

    <%= submit_tag l(:button_save) %>

    +<% end %> diff --git a/app/views/roles/show.api.rsb b/app/views/roles/show.api.rsb new file mode 100644 index 000000000..4e81819cf --- /dev/null +++ b/app/views/roles/show.api.rsb @@ -0,0 +1,9 @@ +api.role do + api.id @role.id + api.name @role.name + api.array :permissions do + @role.permissions.each do |perm| + api.permission(perm.to_s) + end + end +end diff --git a/app/views/search/index.html.erb b/app/views/search/index.html.erb new file mode 100644 index 000000000..936735a72 --- /dev/null +++ b/app/views/search/index.html.erb @@ -0,0 +1,52 @@ +

    <%= l(:label_search) %>

    + +
    +<%= form_tag({}, :method => :get) do %> +<%= label_tag "search-input", l(:description_search), :class => "hidden-for-sighted" %> +

    <%= text_field_tag 'q', @question, :size => 60, :id => 'search-input' %> +<%= javascript_tag "$('#search-input').focus()" %> +<%= project_select_tag %> +<%= hidden_field_tag 'all_words', '', :id => nil %> + +<%= hidden_field_tag 'titles_only', '', :id => nil %> + +

    +

    +<% @object_types.each do |t| %> + +<% end %> +

    + +

    <%= submit_tag l(:button_submit), :name => 'submit' %>

    +<% end %> +
    + +<% if @results %> +
    + <%= render_results_by_type(@results_by_type) unless @scope.size == 1 %> +
    + +

    <%= l(:label_result_plural) %> (<%= @results_by_type.values.sum %>)

    +
    + <% @results.each do |e| %> +
    <%= content_tag('span', h(e.project), :class => 'project') unless @project == e.project %> <%= link_to highlight_tokens(truncate(e.event_title, :length => 255), @tokens), e.event_url %>
    +
    <%= highlight_tokens(e.event_description, @tokens) %> + <%= format_time(e.event_datetime) %>
    + <% end %> +
    +<% end %> + +

    +<% 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"))) %>  +<% 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 %> +

    + +<% html_title(l(:label_search)) -%> diff --git a/app/views/settings/_authentication.html.erb b/app/views/settings/_authentication.html.erb new file mode 100644 index 000000000..d190fab66 --- /dev/null +++ b/app/views/settings/_authentication.html.erb @@ -0,0 +1,38 @@ +<%= form_tag({:action => 'edit', :tab => 'authentication'}) do %> + +
    +

    <%= setting_check_box :login_required %>

    + +

    <%= 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]} %>

    + +

    <%= 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"]] %>

    + +

    <%= setting_check_box :unsubscribe %>

    + +

    <%= setting_text_field :password_min_length, :size => 6 %>

    + +

    <%= setting_check_box :lost_password, :label => :label_password_lost %>

    + +

    <%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %>

    + +

    <%= setting_check_box :rest_api_enabled %>

    + +

    <%= setting_check_box :jsonp_enabled %>

    +
    + +
    + <%= l(:label_session_expiration) %> + +
    +

    <%= 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]} %>

    +

    <%= 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]} %>

    +
    + +

    <%= l(:text_session_expiration_settings) %>

    +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/_display.html.erb b/app/views/settings/_display.html.erb new file mode 100644 index 000000000..1ae5a351a --- /dev/null +++ b/app/views/settings/_display.html.erb @@ -0,0 +1,26 @@ +<%= form_tag({:action => 'edit', :tab => 'display'}) do %> + +
    +

    <%= setting_select :ui_theme, Redmine::Themes.themes.collect {|t| [t.name, t.id]}, :blank => :label_default, :label => :label_theme %>

    + +

    <%= setting_select :default_language, lang_options_for_select(false) %>

    + +

    <%= setting_select :start_of_week, [[day_name(1),'1'], [day_name(6),'6'], [day_name(7),'7']], :blank => :label_language_based %>

    +<% locale = User.current.language.blank? ? ::I18n.locale : User.current.language %> +

    <%= setting_select :date_format, Setting::DATE_FORMATS.collect {|f| [::I18n.l(Date.today, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    + +

    <%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    + +

    <%= setting_select :user_format, @options[:user_format] %>

    + +

    <%= setting_check_box :gravatar_enabled %>

    + +

    <%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid'], ["Retro", 'retro'], ["Mystery man", 'mm']], :blank => :label_none %>

    + +

    <%= setting_check_box :thumbnails_enabled %>

    + +

    <%= setting_text_field :thumbnails_size, :size => 6 %>

    +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/_general.html.erb b/app/views/settings/_general.html.erb new file mode 100644 index 000000000..4ec01995a --- /dev/null +++ b/app/views/settings/_general.html.erb @@ -0,0 +1,40 @@ +<%= form_tag({:action => 'edit'}) do %> + +
    +

    <%= setting_text_field :app_title, :size => 30 %>

    + +

    <%= setting_text_area :welcome_text, :cols => 60, :rows => 5, :class => 'wiki-edit' %>

    +<%= wikitoolbar_for 'settings_welcome_text' %> + +

    <%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %>

    + +

    <%= setting_text_field :per_page_options, :size => 20 %> +<%= l(:text_comma_separated) %>

    + +

    <%= setting_text_field :activity_days_default, :size => 6 %> <%= l(:label_day_plural) %>

    + +

    <%= setting_text_field :host_name, :size => 60 %> +<%= l(:label_example) %>: <%= @guessed_host_and_path %>

    + +

    <%= setting_select :protocol, [['HTTP', 'http'], ['HTTPS', 'https']] %>

    + +

    <%= setting_select :text_formatting, Redmine::WikiFormatting.format_names.collect{|name| [name, name.to_s]}, :blank => :label_none %>

    + +

    <%= setting_check_box :cache_formatted_text %>

    + +

    <%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %>

    + +

    <%= setting_text_field :feeds_limit, :size => 6 %>

    + +

    <%= setting_text_field :file_max_size_displayed, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %>

    + +

    <%= setting_text_field :diff_max_lines_displayed, :size => 6 %>

    + +

    <%= setting_text_field :repositories_encodings, :size => 60 %> +<%= l(:text_comma_separated) %>

    + +<%= call_hook(:view_settings_general_form) %> +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/_issues.html.erb b/app/views/settings/_issues.html.erb new file mode 100644 index 000000000..2efc6e8c2 --- /dev/null +++ b/app/views/settings/_issues.html.erb @@ -0,0 +1,31 @@ +<%= form_tag({:action => 'edit', :tab => 'issues'}, :onsubmit => 'selectAllOptions("selected_columns");') do %> + +
    +

    <%= setting_check_box :cross_project_issue_relations %>

    + +

    <%= setting_select :cross_project_subtasks, cross_project_subtasks_options %>

    + +

    <%= setting_check_box :issue_group_assignment %>

    + +

    <%= setting_check_box :default_issue_start_date_to_creation_date %>

    + +

    <%= setting_check_box :display_subprojects_issues %>

    + +

    <%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %>

    + +

    <%= setting_multiselect :non_working_week_days, (1..7).map {|d| [day_name(d), d.to_s]}, :inline => true %>

    + +

    <%= setting_text_field :issues_export_limit, :size => 6 %>

    + +

    <%= setting_text_field :gantt_items_limit, :size => 6 %>

    +
    + +
    + <%= l(:setting_issue_list_default_columns) %> + <%= render_query_columns_selection( + IssueQuery.new(:column_names => Setting.issue_list_default_columns), + :name => 'settings[issue_list_default_columns]') %> +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/_mail_handler.html.erb b/app/views/settings/_mail_handler.html.erb new file mode 100644 index 000000000..1051436b5 --- /dev/null +++ b/app/views/settings/_mail_handler.html.erb @@ -0,0 +1,23 @@ +<%= form_tag({:action => 'edit', :tab => 'mail_handler'}) do %> + +
    +

    + <%= setting_text_area :mail_handler_body_delimiters, :rows => 5 %> + <%= l(:text_line_separated) %> +

    +
    + +
    +

    <%= setting_check_box :mail_handler_api_enabled, + :onclick => "if (this.checked) { $('#settings_mail_handler_api_key').removeAttr('disabled'); } else { $('#settings_mail_handler_api_key').attr('disabled', true); }"%>

    + +

    <%= 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').attr('disabled')) { $('#settings_mail_handler_api_key').val(randomKey(20)) }" %> +

    +
    + +<%= submit_tag l(:button_save) %> + +<% end %> diff --git a/app/views/settings/_notifications.html.erb b/app/views/settings/_notifications.html.erb new file mode 100644 index 000000000..f746f7ced --- /dev/null +++ b/app/views/settings/_notifications.html.erb @@ -0,0 +1,42 @@ +<% if @deliveries %> +<%= form_tag({:action => 'edit', :tab => 'notifications'}) do %> + +
    +

    <%= setting_text_field :mail_from, :size => 60 %>

    + +

    <%= setting_check_box :bcc_recipients %>

    + +

    <%= setting_check_box :plain_text_mail %>

    + +

    <%= setting_select(:default_notification_option, User.valid_notification_options.collect {|o| [l(o.last), o.first.to_s]}) %>

    + +
    + +
    <%=l(:text_select_mail_notifications)%> +<%= hidden_field_tag 'settings[notified_events][]', '' %> +<% @notifiables.each do |notifiable| %> +<%= notification_field notifiable %> +
    +<% end %> +

    <%= check_all_links('notified_events') %>

    +
    + +
    <%= l(:setting_emails_header) %> +<%= setting_text_area :emails_header, :label => false, :class => 'wiki-edit', :rows => 5 %> +
    + +
    <%= l(:setting_emails_footer) %> +<%= setting_text_area :emails_footer, :label => false, :class => 'wiki-edit', :rows => 5 %> +
    + +
    +<%= link_to l(:label_send_test_email), :controller => 'admin', :action => 'test_email' %> +
    + +<%= submit_tag l(:button_save) %> +<% end %> +<% else %> +
    +<%= simple_format(l(:text_email_delivery_not_configured)) %> +
    +<% end %> diff --git a/app/views/settings/_projects.html.erb b/app/views/settings/_projects.html.erb new file mode 100644 index 000000000..28fd9b578 --- /dev/null +++ b/app/views/settings/_projects.html.erb @@ -0,0 +1,20 @@ +<%= form_tag({:action => 'edit', :tab => 'projects'}) do %> + +
    +

    <%= setting_check_box :default_projects_public %>

    + +

    <%= setting_multiselect(:default_projects_modules, + Redmine::AccessControl.available_project_modules.collect {|m| [l_or_humanize(m, :prefix => "project_module_"), m.to_s]}) %>

    + +

    <%= setting_multiselect(:default_projects_tracker_ids, + Tracker.sorted.all.collect {|t| [t.name, t.id.to_s]}) %>

    + +

    <%= setting_check_box :sequential_project_identifiers %>

    + +

    <%= 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)} ---" %>

    +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/_repositories.html.erb b/app/views/settings/_repositories.html.erb new file mode 100644 index 000000000..5c8ba2432 --- /dev/null +++ b/app/views/settings/_repositories.html.erb @@ -0,0 +1,94 @@ +<%= form_tag({:action => 'edit', :tab => 'repositories'}) do %> + +
    +<%= l(:setting_enabled_scm) %> +<%= hidden_field_tag 'settings[enabled_scm][]', '' %> + + + + + + + <% 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) %> + + + + + + <% end %> +
    <%= l(:text_scm_command) %><%= l(:text_scm_command_version) %>
    + + + <% if enabled %> + <%= + image_tag( + (scm_class.scm_available ? 'true.png' : 'exclamation.png'), + :style => "vertical-align:bottom;" + ) + %> + <%= scm_class.scm_command %> + <% end %> + + <%= scm_class.scm_version_string if enabled %> +
    +

    <%= l(:text_scm_config) %>

    +
    + +
    +

    <%= setting_check_box :autofetch_changesets %>

    + +

    <%= setting_check_box :sys_api_enabled, + :onclick => + "if (this.checked) { $('#settings_sys_api_key').removeAttr('disabled'); } else { $('#settings_sys_api_key').attr('disabled', true); }" %>

    + +

    <%= 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)) }" %> +

    + +

    <%= setting_text_field :repository_log_display_limit, :size => 6 %>

    +
    + +
    +<%= l(:text_issues_ref_in_commit_messages) %> +

    <%= setting_text_field :commit_ref_keywords, :size => 30 %> +<%= l(:text_comma_separated) %>

    + +

    <%= setting_text_field :commit_fix_keywords, :size => 30 %> + <%= l(:label_applied_status) %>: <%= setting_select :commit_fix_status_id, + [["", 0]] + + IssueStatus.sorted.all.collect{ + |status| [status.name, status.id.to_s] + }, + :label => false %> + <%= 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 %> +<%= l(:text_comma_separated) %>

    + +

    <%= setting_check_box :commit_cross_project_ref %>

    + +

    <%= 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); }"%>

    + +

    <%= 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?%>

    +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/settings/edit.html.erb b/app/views/settings/edit.html.erb new file mode 100644 index 000000000..8de53f55c --- /dev/null +++ b/app/views/settings/edit.html.erb @@ -0,0 +1,5 @@ +

    <%= l(:label_settings) %>

    + +<%= render_tabs administration_settings_tabs %> + +<% html_title(l(:label_settings), l(:label_administration)) -%> diff --git a/app/views/settings/plugin.html.erb b/app/views/settings/plugin.html.erb new file mode 100644 index 000000000..46c4678af --- /dev/null +++ b/app/views/settings/plugin.html.erb @@ -0,0 +1,10 @@ +

    <%= l(:label_settings) %>: <%=h @plugin.name %>

    + +
    +<%= form_tag({:action => 'plugin'}) do %> +
    +<%= render :partial => @partial, :locals => {:settings => @settings}%> +
    +<%= submit_tag l(:button_apply) %> +<% end %> +
    diff --git a/app/views/tags/_related_tags.html.erb b/app/views/tags/_related_tags.html.erb new file mode 100644 index 000000000..08c588a11 --- /dev/null +++ b/app/views/tags/_related_tags.html.erb @@ -0,0 +1,14 @@ +<% if related_tags %> +
      + <% for rt in related_tags %> +
    • + <%= link_to image_tag("/images/add.png"),:action => "add_tag",:remote => true,:tag => rt %> + <%= rt %> + <% @issue_size = Issue.tagged_with("#{rt}").size %> + <% @project_size = Project.tagged_with(rt).size %> + <% @user_size = User.tagged_with("#{rt}").size %> + (<%= @user_size + @project_size + @issue_size %>) +
    • + <% end %> +
    +<% end %> diff --git a/app/views/tags/_selected_tags.html.erb b/app/views/tags/_selected_tags.html.erb new file mode 100644 index 000000000..0eacecd32 --- /dev/null +++ b/app/views/tags/_selected_tags.html.erb @@ -0,0 +1,15 @@ +<% if selected_tags %> +
      + <% for sg in selected_tags %> +
    • + <%= link_to image_tag("/images/delete.png"),:action => "delete_tag",:remote=>true,:tag => sg %> + <%= sg %> + <% @issue_size = Issue.tagged_with("#{sg}").size %> + <% @project_size = Project.tagged_with(sg).size %> + <% @user_size = User.tagged_with("#{sg}").size %> + (<%= @user_size + @project_size + @issue_size %>) +
    • + <% end %> +
    +<% end %> + diff --git a/app/views/tags/_show_results.html.erb b/app/views/tags/_show_results.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/tags/_tag_search_results.html.erb b/app/views/tags/_tag_search_results.html.erb new file mode 100644 index 000000000..7fba13974 --- /dev/null +++ b/app/views/tags/_tag_search_results.html.erb @@ -0,0 +1,37 @@ +
      + <% if issues_results.size > 0 %> +
      +

      Issues:

      + <% issues_results.each do |issue| %> +
    • + 问题:<%= link_to "#{issue.subject}",:controller => "issues",:action => "show",:id => issue.id %> +
    • + <% end %> + <% end %> + + <% if users_results.size > 0 %> +
      +

      Users:

      + <% users_results.each do |user| %> +
    • + 用户å:<%= link_to ("#{user.firstname+user.lastname}"), + :controller => "users",:action => "show",:id => user.id %> +
      + 用户邮箱:<%= mail_to(h(user.mail)) %> +
    • + <% end %> + <% end %> + + <% if projects_results.size > 0 %> +
      +

      Projects:

      + <% projects_results.each do |project| %> +
    • + 项目å称:<%= link_to project.name,:controller => "projects",:action => "show",:id => project.id %> +
      + 项目æè¿°ï¼š<%= project.description %>; + +
    • + <% end %> + <% end %> +
    \ No newline at end of file diff --git a/app/views/tags/add_tag.js.erb b/app/views/tags/add_tag.js.erb new file mode 100644 index 000000000..610fb12c3 --- /dev/null +++ b/app/views/tags/add_tag.js.erb @@ -0,0 +1,9 @@ +$('#selected_tags').html('<%= j(render :partial => "selected_tags", +:locals => {:selected_tags => $selected_tags })%>'); +$('#related_tags').html('<%= j(render :partial => "related_tags", + :locals => {:related_tags => $related_tags })%>') + +$('#show_results').html('<%= j(render :partial => "tag_search_results",:locals => {:issues_results => @issues_results, + :projects_results => @projects_results,:users_results => @users_results })%>') + + \ No newline at end of file diff --git a/app/views/tags/delete_tag.js.erb b/app/views/tags/delete_tag.js.erb new file mode 100644 index 000000000..ca714ccfa --- /dev/null +++ b/app/views/tags/delete_tag.js.erb @@ -0,0 +1,8 @@ +$('#selected_tags').html('<%= j(render :partial => "selected_tags", +:locals => {:selected_tags => $selected_tags })%>'); +$('#related_tags').html('<%= j(render :partial => "related_tags", +:locals => {:related_tags => $related_tags })%>') + +$('#show_results').html('<%= j(render :partial => "tag_search_results",:locals => {:issues_results => @issues_results, +:projects_results => @projects_results,:users_results => @users_results })%>') + diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb new file mode 100644 index 000000000..7b4890830 --- /dev/null +++ b/app/views/tags/index.html.erb @@ -0,0 +1,31 @@ +
    +
      +
    • + Selected Tags +
    • +
      + <%= render :partial => "selected_tags",:locals => {:selected_tags => $selected_tags }%> +
      +
    • + Related Tags +
    • + +
    +
    + +
    +

    Search Results

    +
    + <%= link_to "Issue",:action => "index"%>(<%= @issues_tags_num %>)| + <%= link_to "Project",:action => "index"%>(<%= @projects_tags_num %>) | + <%= link_to "User",:action => "index"%>(<%= @users_tags_num %>) +
    +
    + <%= render :partial => "tag_search_results",:locals => {:issues_results => @issues_results, + :projects_results => @projects_results,:users_results => @users_results }%> +
    +
    + + diff --git a/app/views/test/_message.html.erb b/app/views/test/_message.html.erb new file mode 100644 index 000000000..a8c3cfacf --- /dev/null +++ b/app/views/test/_message.html.erb @@ -0,0 +1,9 @@ +
    +
    + +

    <%= l(:label_message) %> (<%= message.size %>)

    +<% if message.size > 0 %> + <%= message_list(message) %> +<% else %> + <%= l(:label_none) %> +<% end %> \ No newline at end of file diff --git a/app/views/test/_new.html.erb b/app/views/test/_new.html.erb new file mode 100644 index 000000000..e589a3a0e --- /dev/null +++ b/app/views/test/_new.html.erb @@ -0,0 +1,16 @@ +

    <%= l(:label_leave_message_to, :name => "user") %>

    + +<%= form_tag({:controller => 'test', + :action => 'create', + :user_id => user.id}, + :remote => true, + :method => :post, + :id => 'new-watcher-form') do %> + +

    <%= label_tag 'user_search', l(:label_leave_message) %><%= text_field_tag 'user_search', nil %>

    + +

    + <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

    +<% end %> diff --git a/app/views/test/create.js.erb b/app/views/test/create.js.erb new file mode 100644 index 000000000..f662bdb53 --- /dev/null +++ b/app/views/test/create.js.erb @@ -0,0 +1 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'test/message', :locals => {:message => @message})) %>'); diff --git a/app/views/test/destroy.js.erb b/app/views/test/destroy.js.erb new file mode 100644 index 000000000..f662bdb53 --- /dev/null +++ b/app/views/test/destroy.js.erb @@ -0,0 +1 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'test/message', :locals => {:message => @message})) %>'); diff --git a/app/views/test/index.html.erb b/app/views/test/index.html.erb new file mode 100644 index 000000000..97634e965 --- /dev/null +++ b/app/views/test/index.html.erb @@ -0,0 +1,3 @@ +

    test

    + + \ No newline at end of file diff --git a/app/views/test/new.js.erb b/app/views/test/new.js.erb new file mode 100644 index 000000000..bd3da2e2a --- /dev/null +++ b/app/views/test/new.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'test/new', :locals => {:user => @user}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-watcher'); diff --git a/app/views/timelog/_date_range.html.erb b/app/views/timelog/_date_range.html.erb new file mode 100644 index 000000000..a889f160c --- /dev/null +++ b/app/views/timelog/_date_range.html.erb @@ -0,0 +1,34 @@ +
    +
    "> + <%= l(:label_filter_plural) %> +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    + +
    + +

    + <%= 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' %> +

    + +
    +<% query_params = params.slice(:f, :op, :v, :sort) %> +
      +
    • <%= link_to(l(:label_details), query_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }), + :class => (action_name == 'index' ? 'selected' : nil)) %>
    • +
    • <%= link_to(l(:label_report), query_params.merge({:controller => 'timelog', :action => 'report', :project_id => @project, :issue_id => @issue}), + :class => (action_name == 'report' ? 'selected' : nil)) %>
    • +
    +
    diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb new file mode 100644 index 000000000..3256feaac --- /dev/null +++ b/app/views/timelog/_form.html.erb @@ -0,0 +1,32 @@ +<%= error_messages_for 'time_entry' %> +<%= back_url_hidden_field_tag %> + +
    + <% if @time_entry.new_record? %> + <% if params[:project_id] || @time_entry.issue %> + <%= f.hidden_field :project_id %> + <% else %> +

    <%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %>

    + <% end %> + <% end %> +

    + <%= f.text_field :issue_id, :size => 6 %> + <%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %> +

    +

    <%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %>

    +

    <%= f.text_field :hours, :size => 6, :required => true %>

    +

    <%= f.text_field :comments, :size => 100, :maxlength => 255 %>

    +

    <%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %>

    + <% @time_entry.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :time_entry, value %>

    + <% end %> + <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %> +
    + +<%= 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 --git a/app/views/timelog/_list.html.erb b/app/views/timelog/_list.html.erb new file mode 100644 index 000000000..522b13032 --- /dev/null +++ b/app/views/timelog/_list.html.erb @@ -0,0 +1,41 @@ +<%= form_tag({}) do -%> +<%= hidden_field_tag 'back_url', url_for(params) %> +
    + + + + + <% @query.inline_columns.each do |column| %> + <%= column_header(column) %> + <% end %> + + + + +<% entries.each do |entry| -%> + hascontextmenu"> + + <%= raw @query.inline_columns.map {|column| ""}.join %> + + +<% end -%> + +
    + <%= link_to image_tag('toggle_check.png'), + {}, + :onclick => 'toggleIssuesSelection(this); return false;', + :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> +
    <%= check_box_tag("ids[]", entry.id, false, :id => nil) %>#{column_content(column, entry)} + <% 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 -%> +
    +
    +<% end -%> + +<%= context_menu time_entries_context_menu_path %> diff --git a/app/views/timelog/_report_criteria.html.erb b/app/views/timelog/_report_criteria.html.erb new file mode 100644 index 000000000..9a5d142f2 --- /dev/null +++ b/app/views/timelog/_report_criteria.html.erb @@ -0,0 +1,19 @@ +<% @report.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? -%> + +<%= ("" * level).html_safe %> +<%= h(format_criteria_value(@report.available_criteria[criterias[level]], value)) %> +<%= ("" * (criterias.length - level - 1)).html_safe -%> + <% total = 0 -%> + <% @report.periods.each do |period| -%> + <% sum = sum_hours(select_hours(hours_for_value, @report.columns, period.to_s)); total += sum -%> + <%= html_hours("%.2f" % sum) if sum > 0 %> + <% end -%> + <%= html_hours("%.2f" % total) if total > 0 %> + +<% if criterias.length > level+1 -%> + <%= render(:partial => 'report_criteria', :locals => {:criterias => criterias, :hours => hours_for_value, :level => (level + 1)}) %> +<% end -%> + +<% end %> diff --git a/app/views/timelog/bulk_edit.html.erb b/app/views/timelog/bulk_edit.html.erb new file mode 100644 index 000000000..caabc18a2 --- /dev/null +++ b/app/views/timelog/bulk_edit.html.erb @@ -0,0 +1,50 @@ +

    <%= l(:label_bulk_edit_selected_time_entries) %>

    + +
      +<% @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 %> +
    + +<%= 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 %> +
    +
    +

    + + <%= text_field :time_entry, :issue_id, :size => 6 %> +

    + +

    + + <%= text_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %> +

    + +

    + + <%= text_field :time_entry, :hours, :size => 6 %> +

    + + <% if @available_activities.any? %> +

    + + <%= select_tag('time_entry[activity_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_activities, :id, :name)) %> +

    + <% end %> + +

    + + <%= text_field(:time_entry, :comments, :size => 100) %> +

    + + <% @custom_fields.each do |custom_field| %> +

    <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %>

    + <% end %> + + <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %> +
    +
    + +

    <%= submit_tag l(:button_submit) %>

    +<% end %> diff --git a/app/views/timelog/edit.html.erb b/app/views/timelog/edit.html.erb new file mode 100644 index 000000000..7c6ac5b80 --- /dev/null +++ b/app/views/timelog/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_spent_time) %>

    + +<%= labelled_form_for @time_entry, :url => project_time_entry_path(@time_entry.project, @time_entry) do |f| %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/timelog/index.api.rsb b/app/views/timelog/index.api.rsb new file mode 100644 index 000000000..d281e89b2 --- /dev/null +++ b/app/views/timelog/index.api.rsb @@ -0,0 +1,18 @@ +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 + + render_api_custom_values time_entry.custom_field_values, api + end + end +end diff --git a/app/views/timelog/index.html.erb b/app/views/timelog/index.html.erb new file mode 100644 index 000000000..d73bd1302 --- /dev/null +++ b/app/views/timelog/index.html.erb @@ -0,0 +1,48 @@ +
    +<%= 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) %> +
    + +<%= render_timelog_breadcrumb %> + +

    <%= l(:label_spent_time) %>

    + +<%= form_tag({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %> +<%= render :partial => 'date_range' %> +<% end %> + +
    +

    <%= l(:label_total_time) %>: <%= html_hours(l_hours(@total_hours)) %>

    +
    + +<% unless @entries.empty? %> +<%= render :partial => 'list', :locals => { :entries => @entries }%> +

    <%= pagination_links_full @entry_pages, @entry_count %>

    + +<% 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 %> + + +<% 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 --git a/app/views/timelog/new.html.erb b/app/views/timelog/new.html.erb new file mode 100644 index 000000000..c740e6df9 --- /dev/null +++ b/app/views/timelog/new.html.erb @@ -0,0 +1,8 @@ +

    <%= l(:label_spent_time) %>

    + +<%= labelled_form_for @time_entry, :url => time_entries_path do |f| %> + <%= hidden_field_tag 'project_id', params[:project_id] if params[:project_id] %> + <%= render :partial => 'form', :locals => {:f => f} %> + <%= submit_tag l(:button_create) %> + <%= submit_tag l(:button_create_and_continue), :name => 'continue' %> +<% end %> diff --git a/app/views/timelog/report.html.erb b/app/views/timelog/report.html.erb new file mode 100644 index 000000000..30a58a732 --- /dev/null +++ b/app/views/timelog/report.html.erb @@ -0,0 +1,74 @@ +
    +<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %> +
    + +<%= render_timelog_breadcrumb %> + +

    <%= l(:label_spent_time) %>

    + +<%= 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' %> + +

    : <%= 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();" %> + + : <%= 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' %>

    +<% end %> + +<% unless @report.criteria.empty? %> +
    +

    <%= l(:label_total_time) %>: <%= html_hours(l_hours(@report.total_hours)) %>

    +
    + +<% unless @report.hours.empty? %> +
    + + + +<% @report.criteria.each do |criteria| %> + +<% end %> +<% columns_width = (40 / (@report.periods.length+1)).to_i %> +<% @report.periods.each do |period| %> + +<% end %> + + + + +<%= render :partial => 'report_criteria', :locals => {:criterias => @report.criteria, :hours => @report.hours, :level => 0} %> + + + <%= ('' * (@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 -%> + + <% end -%> + + + +
    <%= l_or_humanize(@report.available_criteria[criteria][:label]) %><%= period %><%= l(:label_total_time) %>
    <%= l(:label_total_time) %><%= html_hours("%.2f" % sum) if sum > 0 %><%= html_hours("%.2f" % total) if total > 0 %>
    +
    + +<% other_formats_links do |f| %> + <%= f.link_to 'CSV', :url => params %> +<% end %> +<% end %> +<% end %> + +<% html_title l(:label_spent_time), l(:label_report) %> + diff --git a/app/views/timelog/show.api.rsb b/app/views/timelog/show.api.rsb new file mode 100644 index 000000000..7fce2529a --- /dev/null +++ b/app/views/timelog/show.api.rsb @@ -0,0 +1,14 @@ +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 + + render_api_custom_values @time_entry.custom_field_values, api +end diff --git a/app/views/trackers/_form.html.erb b/app/views/trackers/_form.html.erb new file mode 100644 index 000000000..9039bba68 --- /dev/null +++ b/app/views/trackers/_form.html.erb @@ -0,0 +1,52 @@ +<%= error_messages_for 'tracker' %> + +
    +
    + +

    <%= f.text_field :name, :required => true %>

    +

    <%= f.check_box :is_in_roadmap %>

    + +

    + + <% Tracker::CORE_FIELDS.each do |field| %> + + <% end %> +

    +<%= hidden_field_tag 'tracker[core_fields][]', '' %> + +<% if IssueCustomField.all.any? %> +

    + + <% IssueCustomField.all.each do |field| %> + + <% end %> +

    +<%= hidden_field_tag 'tracker[custom_field_ids][]', '' %> +<% end %> + +<% if @tracker.new_record? && @trackers.any? %> +

    +<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@trackers, :id, :name)) %>

    +<% end %> + +
    +<%= submit_tag l(@tracker.new_record? ? :button_create : :button_save) %> +
    + +
    +<% if @projects.any? %> +
    <%= l(:label_project_plural) %> +<%= render_project_nested_lists(@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) %> +

    <%= check_all_links 'tracker_project_ids' %>

    +
    +<% end %> +
    diff --git a/app/views/trackers/edit.html.erb b/app/views/trackers/edit.html.erb new file mode 100644 index 000000000..343e53fe8 --- /dev/null +++ b/app/views/trackers/edit.html.erb @@ -0,0 +1,5 @@ +

    <%= link_to l(:label_tracker_plural), trackers_path %> » <%=h @tracker %>

    + +<%= labelled_form_for @tracker do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<% end %> diff --git a/app/views/trackers/fields.html.erb b/app/views/trackers/fields.html.erb new file mode 100644 index 000000000..48cfb17a4 --- /dev/null +++ b/app/views/trackers/fields.html.erb @@ -0,0 +1,77 @@ +

    <%= link_to l(:label_tracker_plural), trackers_path %> » <%= l(:field_summary) %>

    + +<% if @trackers.any? %> + <%= form_tag fields_trackers_path do %> +
    + + + + + <% @trackers.each do |tracker| %> + + <% end %> + + + + + + + <% Tracker::CORE_FIELDS.each do |field| %> + "> + + <% @trackers.each do |tracker| %> + + <% end %> + + <% end %> + <% if @custom_fields.any? %> + + + + <% @custom_fields.each do |field| %> + "> + + <% @trackers.each do |tracker| %> + + <% end %> + + <% end %> + <% end %> + +
    + <%= tracker.name %> + <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.tracker-#{tracker.id}')", + :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %> +
    +   + <%= l(:field_core_fields) %> +
    + <%= 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$/, '')) %> + + <%= check_box_tag "trackers[#{tracker.id}][core_fields][]", field, tracker.core_fields.include?(field), + :class => "tracker-#{tracker.id} core-field-#{field}" %> +
    +   + <%= l(:label_custom_field_plural) %> +
    + <%= 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 %> + + <%= check_box_tag "trackers[#{tracker.id}][custom_field_ids][]", field.id, tracker.custom_fields.include?(field), + :class => "tracker-#{tracker.id} custom-field-#{field.id}" %> +
    +
    +

    <%= submit_tag l(:button_save) %>

    + <% @trackers.each do |tracker| %> + <%= hidden_field_tag "trackers[#{tracker.id}][core_fields][]", '' %> + <%= hidden_field_tag "trackers[#{tracker.id}][custom_field_ids][]", '' %> + <% end %> + <% end %> +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +<% html_title l(:field_summary) %> diff --git a/app/views/trackers/index.api.rsb b/app/views/trackers/index.api.rsb new file mode 100644 index 000000000..a37c552a8 --- /dev/null +++ b/app/views/trackers/index.api.rsb @@ -0,0 +1,8 @@ +api.array :trackers do + @trackers.each do |tracker| + api.tracker do + api.id tracker.id + api.name tracker.name + end + end +end diff --git a/app/views/trackers/index.html.erb b/app/views/trackers/index.html.erb new file mode 100644 index 000000000..abcf84d82 --- /dev/null +++ b/app/views/trackers/index.html.erb @@ -0,0 +1,39 @@ +
    +<%= 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' %> +
    + +

    <%=l(:label_tracker_plural)%>

    + + + + + + + + + +<% for tracker in @trackers %> + "> + + + + + +<% end %> + +
    <%=l(:label_tracker)%><%=l(:button_sort)%>
    <%= link_to h(tracker.name), edit_tracker_path(tracker) %> + <% unless tracker.workflow_rules.count > 0 %> + + <%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:tracker_id => tracker) %>) + + <% end %> + + <%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %> + + <%= delete_link tracker_path(tracker) %> +
    + +

    <%= pagination_links_full @tracker_pages %>

    + +<% html_title(l(:label_tracker_plural)) -%> diff --git a/app/views/trackers/new.html.erb b/app/views/trackers/new.html.erb new file mode 100644 index 000000000..d636499a1 --- /dev/null +++ b/app/views/trackers/new.html.erb @@ -0,0 +1,5 @@ +

    <%= link_to l(:label_tracker_plural), trackers_path %> » <%=l(:label_tracker_new)%>

    + +<%= labelled_form_for @tracker do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<% end %> diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb new file mode 100644 index 000000000..ddc826fa8 --- /dev/null +++ b/app/views/users/_form.html.erb @@ -0,0 +1,51 @@ +<%= error_messages_for 'user' %> + +
    + +
    +
    + <%=l(:label_information_plural)%> +

    <%= f.text_field :login, :required => true, :size => 25 %>

    +

    <%= f.text_field :firstname, :required => true %>

    +

    <%= f.text_field :lastname, :required => true %>

    +

    <%= f.text_field :mail, :required => true %>

    +

    <%= f.select :language, lang_options_for_select %>

    + <% if Setting.openid? %> +

    <%= f.text_field :identity_url %>

    + <% end %> + + <% @user.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :user, value %>

    + <% end %> + +

    <%= f.check_box :admin, :disabled => (@user == User.current) %>

    + <%= call_hook(:view_users_form, :user => @user, :form => f) %> +
    + +
    + <%=l(:label_authentication)%> + <% unless @auth_sources.empty? %> +

    <%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {$('#password_fields').show();} else {$('#password_fields').hide();}" %>

    + <% end %> +
    +

    <%= f.password_field :password, :required => true, :size => 25 %> + <%= l(:text_caracters_minimum, :count => Setting.password_min_length) %>

    +

    <%= f.password_field :password_confirmation, :required => true, :size => 25 %>

    +
    +
    +
    + +
    +
    + <%=l(:field_mail_notification)%> + <%= render :partial => 'users/mail_notifications' %> +
    + +
    + <%=l(:label_preferences)%> + <%= render :partial => 'users/preferences' %> +
    +
    +
    +
    + diff --git a/app/views/users/_general.html.erb b/app/views/users/_general.html.erb new file mode 100644 index 000000000..0daa421c7 --- /dev/null +++ b/app/views/users/_general.html.erb @@ -0,0 +1,7 @@ +<%= labelled_form_for @user do |f| %> + <%= render :partial => 'form', :locals => { :f => f } %> + <% if @user.active? && email_delivery_enabled? -%> +

    + <% end -%> +

    <%= submit_tag l(:button_save) %>

    +<% end %> diff --git a/app/views/users/_groups.html.erb b/app/views/users/_groups.html.erb new file mode 100644 index 000000000..e24296ef0 --- /dev/null +++ b/app/views/users/_groups.html.erb @@ -0,0 +1,9 @@ +<%= form_for(:user, :url => { :action => 'update' }, :html => {:method => :put}) do %> +
    +<% Group.all.sort.each do |group| %> +
    +<% end %> +<%= hidden_field_tag 'user[group_ids][]', '' %> +
    +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/users/_leave_message.html.erb b/app/views/users/_leave_message.html.erb new file mode 100644 index 000000000..5c2780ad2 --- /dev/null +++ b/app/views/users/_leave_message.html.erb @@ -0,0 +1,27 @@ +

    <%= l(:permission_add_issue_watchers) %>

    + +<%= form_tag({:controller => 'users', + :action => (user ? 'create' : 'append'), + :object_type => (user && user.class.name.underscore), + :object_id => user, + :project_id => @project}, + :remote => true, + :method => :post, + :id => 'new-watcher-form') do %> + +

    <%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %>

    + <%= 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) }')" %> + +
    + <%= principals_check_box_tags 'watcher[user_ids][]', (watched ? watched.addable_watcher_users : User.active.all(:limit => 100)) %> +
    + +

    + <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

    +<% end %> diff --git a/app/views/users/_mail_notifications.html.erb b/app/views/users/_mail_notifications.html.erb new file mode 100644 index 000000000..ee6ccb00b --- /dev/null +++ b/app/views/users/_mail_notifications.html.erb @@ -0,0 +1,27 @@ +

    +<%= 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") {$("#notified-projects").show();} else {$("#notified-projects").hide();}' + ) %> +

    +<%= content_tag 'div', :id => 'notified-projects', :style => (@user.mail_notification == 'selected' ? '' : 'display:none;') do %> + <%= render_project_nested_lists_new(@user.projects) do |project| + content_tag('label', + check_box_tag( + 'notified_project_ids[]', + project.id, + @user.notified_projects_ids.include?(project.id) + ) + ' ' + h(project.name) + ) + end %> +

    <%= l(:text_user_mail_option) %>

    +<% end %> +

    + +

    diff --git a/app/views/users/_memberships.html.erb b/app/views/users/_memberships.html.erb new file mode 100644 index 000000000..5f61d2ce2 --- /dev/null +++ b/app/views/users/_memberships.html.erb @@ -0,0 +1,67 @@ +<% roles = Role.find_all_givable %> +<% projects = Project.active.all %> + +
    +<% if @user.memberships.any? %> + + + + + + <%= call_hook(:view_users_memberships_table_header, :user => @user )%> + + + <% @user.memberships.each do |membership| %> + <% next if membership.new_record? %> + + + + + <%= call_hook(:view_users_memberships_table_row, :user => @user, :membership => membership, :roles => roles, :projects => projects )%> + + <% end; reset_cycle %> + +
    <%= l(:label_project) %><%= l(:label_role_plural) %>
    + <%= link_to_project membership.project %> + + <%=h membership.roles.sort.collect(&:to_s).join(', ') %> + <%= form_for(:membership, :remote => true, + :url => user_membership_path(@user, membership), :method => :put, + :html => {:id => "member-#{membership.id}-roles-form", + :style => 'display:none;'}) do %> +

    <% roles.each do |role| %> +
    + <% end %>

    + <%= hidden_field_tag 'membership[role_ids][]', '' %> +

    <%= submit_tag l(:button_change) %> + <%= link_to_function l(:button_cancel), + "$('#member-#{membership.id}-roles').show(); $('#member-#{membership.id}-roles-form').hide(); return false;" + %>

    + <% end %> +
    + <%= 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? %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> +
    + +
    +<% if projects.any? %> +
    <%=l(:label_project_new)%> +<%= form_for(:membership, :remote => true, :url => user_memberships_path(@user)) do %> +<%= select_tag 'membership[project_id]', options_for_membership_project_select(@user, projects) %> +

    <%= l(:label_role_plural) %>: +<% roles.each do |role| %> + +<% end %>

    +

    <%= submit_tag l(:button_add) %>

    +<% end %> +
    +<% end %> +
    diff --git a/app/views/users/_preferences.html.erb b/app/views/users/_preferences.html.erb new file mode 100644 index 000000000..fb72d475a --- /dev/null +++ b/app/views/users/_preferences.html.erb @@ -0,0 +1,6 @@ +<%= labelled_fields_for :pref, @user.pref do |pref_fields| %> +

    <%= pref_fields.check_box :hide_mail %>

    +

    <%= pref_fields.time_zone_select :time_zone, nil, :include_blank => true %>

    +

    <%= pref_fields.select :comments_sorting, [[l(:label_chronological_order), 'asc'], [l(:label_reverse_chronological_order), 'desc']] %>

    +

    <%= pref_fields.check_box :warn_on_leaving_unsaved %>

    +<% end %> diff --git a/app/views/users/blocks/_calendar.html.erb b/app/views/users/blocks/_calendar.html.erb new file mode 100644 index 000000000..41ca18a10 --- /dev/null +++ b/app/views/users/blocks/_calendar.html.erb @@ -0,0 +1,6 @@ +

    <%= l(:label_calendar) %>

    + +<% 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 --git a/app/views/users/blocks/_issuesassignedtome.html.erb b/app/views/users/blocks/_issuesassignedtome.html.erb new file mode 100644 index 000000000..02d8c9aa6 --- /dev/null +++ b/app/views/users/blocks/_issuesassignedtome.html.erb @@ -0,0 +1,18 @@ +

    <%=l(:label_assigned_to_me_issues)%> (<%= Issue.visible.open.count(:conditions => {:assigned_to_id => ([User.current.id] + User.current.group_ids)})%>)

    + +<% assigned_issues = issuesassignedtome_items %> +<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %> +<% if assigned_issues.length > 0 %> +

    <%= link_to l(:label_issue_view_all), :controller => 'issues', + :action => 'index', + :set_filter => 1, + :assigned_to_id => 'me', + :sort => 'priority:desc,updated_on:desc' %>

    +<% 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 --git a/app/views/users/destroy_membership.js.erb b/app/views/users/destroy_membership.js.erb new file mode 100644 index 000000000..53b769a73 --- /dev/null +++ b/app/views/users/destroy_membership.js.erb @@ -0,0 +1 @@ +$('#tab-content-memberships').html('<%= escape_javascript(render :partial => 'users/memberships') %>'); diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 000000000..01875ab68 --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,11 @@ +
    +<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %> +<%= change_status_link(@user) %> +<%= delete_link user_path(@user) if User.current != @user %> +
    + +

    <%= link_to l(:label_user_plural), users_path %> » <%=h @user.login %>

    + +<%= render_tabs user_settings_tabs %> + +<% html_title(l(:label_user), @user.login, l(:label_administration)) -%> diff --git a/app/views/users/edit_membership.js.erb b/app/views/users/edit_membership.js.erb new file mode 100644 index 000000000..d9ad2f355 --- /dev/null +++ b/app/views/users/edit_membership.js.erb @@ -0,0 +1,6 @@ +<% if @membership.valid? %> + $('#tab-content-memberships').html('<%= escape_javascript(render :partial => 'users/memberships') %>'); + $("#member-<%= @membership.id %>").effect("highlight"); +<% else %> + alert('<%= raw(escape_javascript(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))) %>'); +<% end %> diff --git a/app/views/users/index.api.rsb b/app/views/users/index.api.rsb new file mode 100644 index 000000000..4265a4be4 --- /dev/null +++ b/app/views/users/index.api.rsb @@ -0,0 +1,15 @@ +api.array :users, api_meta(:total_count => @user_count, :offset => @offset, :limit => @limit) do + @users.each do |user| + api.user do + api.id user.id + api.login user.login + api.firstname user.firstname + api.lastname user.lastname + api.mail user.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 + end + end +end diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb new file mode 100644 index 000000000..99b26aba6 --- /dev/null +++ b/app/views/users/index.html.erb @@ -0,0 +1,155 @@ +<% if User.current.admin? %> +
    + <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %> +
    + +

    <%= l(:label_user_plural)%>

    + +<%= form_tag(users_path, :method => :get) do %> +
    + + <%= l(:label_filter_plural) %> + + + <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + + <% if @groups.present? %> + + <%= 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 %> + + + <%= 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' %> +
    +<% end %> +  + +
    + + + + <%= 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') %> + + + + + <% for user in @users -%> + "> + + + + + + + + + + <% end -%> + +
    <%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %><%= h(user.firstname) %><%= h(user.lastname) %><%= checked_image user.admin? %><%= format_time(user.created_on) %> <%= change_status_link(user) %> + <%= delete_link user_path(user, :back_url => users_path(params)) unless User.current == user %>
    +
    + + +<% html_title(l(:label_user_plural)) -%> + +<% else %> +
    + <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %> +
    + +

    <%= l(:label_user_plural)%>

    + +<%= form_tag(users_path, :method => :get) do %> +
    + + <%= l(:label_filter_plural) %> + + + <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + + <% if @groups.present? %> + + <%= 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 %> + + + <%= 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' %> +
    +<% end %> +  + +
    + + + <% for user in @users -%> +
    + <%= content_tag "p", "#{date_format_local(user.created_on)}#{l(:label_member_since)}", :class => "float_right member_since" %> + <%= get_avatar?(user) ? (link_to image_tag(avatar_image(user), :class => 'avatar'), :class => "avatar") : (link_to image_tag("/images/12_50.png", :class => 'avatar'), :class => "avatar") %> + <%= content_tag "div", link_to_user(user), :class => "nomargin avatar_name" %> + <%= content_tag "div", content_tag("p", user.firstname), :class => "clear avatar_name" %> +

    + <% unless user.memberships.empty? %> + <%= l(:label_contribute_to, :project_count => "#{user.memberships.count}") %> + <% for member in user.memberships %> + <%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %> + <% end %> + <% end %> +

    +

    + <%= user.changesets.count == 0 ? '' : "#{l(:label_total_commit, :total_commit => user.changesets.count)}" %> | managed 7 projects | Most experience in c++ +

    +
    + <% end -%> +
    + + + +<% html_title(l(:label_user_plural)) -%> +<% end -%> diff --git a/app/views/users/leave_message.js.erb b/app/views/users/leave_message.js.erb new file mode 100644 index 000000000..f4a8ac7a0 --- /dev/null +++ b/app/views/users/leave_message.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'users/leave_message', :locals => {:user => @user}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-watcher'); diff --git a/app/views/users/list.api.rsb b/app/views/users/list.api.rsb new file mode 100644 index 000000000..4265a4be4 --- /dev/null +++ b/app/views/users/list.api.rsb @@ -0,0 +1,15 @@ +api.array :users, api_meta(:total_count => @user_count, :offset => @offset, :limit => @limit) do + @users.each do |user| + api.user do + api.id user.id + api.login user.login + api.firstname user.firstname + api.lastname user.lastname + api.mail user.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 + end + end +end diff --git a/app/views/users/list.html.erb b/app/views/users/list.html.erb new file mode 100644 index 000000000..4cceaee35 --- /dev/null +++ b/app/views/users/list.html.erb @@ -0,0 +1,81 @@ +
    + <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %> +
    + +

    <%= l(:label_user_plural)%>

    + +<%= form_tag(users_path, :method => :get) do %> +
    + + <%= l(:label_filter_plural) %> + + + <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + + <% if @groups.present? %> + + <%= 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 %> + + + <%= 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' %> +
    +<% end %> +  + +
    + + + <% for user in @users -%> +
    + <%= content_tag "p", "Trustie2 member since #{format_time(user.created_on)}", :class => "float_right member_since" %> + <%= link_to image_tag(avatar_image(user), :class => 'avatar'), :class => "avatar" %> + <%= content_tag "div", link_to_user(user), :class => "nomargin avatar_name" %> + <%= content_tag "div", content_tag("p", user.firstname), :class => "clear avatar_name" %> +

    + Contributes to <%= user.id%> projects including +

    +

    + 14168 total commits to 18 projects | managed 7 projects | Most experience in c++ +

    +
    + <% end -%> +
    + + + +<% html_title(l(:label_user_plural)) -%> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 000000000..e21129140 --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,30 @@ +

    <%= link_to l(:label_user_plural), users_path %> » <%=l(:label_user_new)%>

    + +<%= labelled_form_for @user do |f| %> + <%= render :partial => 'form', :locals => { :f => f } %> + <% if email_delivery_enabled? %> +

    + <% end %> +

    + <%= submit_tag l(:button_create) %> + <%= submit_tag l(:button_create_and_continue), :name => 'continue' %> +

    +<% 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 --git a/app/views/users/show.api.rsb b/app/views/users/show.api.rsb new file mode 100644 index 000000000..7168cb94f --- /dev/null +++ b/app/views/users/show.api.rsb @@ -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 --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 000000000..8c58dd7f2 --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,26 @@ + +<% unless @events_by_day.empty? %> +
    +<% @events_by_day.keys.sort.reverse.each do |day| %> +<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%> + + + + + + <% end %> +
    + + + + + + + + + + + +
    <%= content_tag('span', h(e.project), :class => 'project') %> æœ‰äº†æœ€æ–°åŠ¨æ€ <%= link_to format_activity_title(e.event_title), e.event_url %>

    <%= format_activity_description(e.event_description) %>

    <%= format_activity_day(day) %>
    <% end %> +
    +<% end %> diff --git a/app/views/users/show_old.html.erb b/app/views/users/show_old.html.erb new file mode 100644 index 000000000..1f75b8d66 --- /dev/null +++ b/app/views/users/show_old.html.erb @@ -0,0 +1,343 @@ + + +
    + <%= link_to(l(:button_edit), edit_user_path(@user), :class => 'icon icon-edit') if User.current.admin? %> +
    + +

    <%= h @user.name %>

    + + +
    +
    + +
    + + + + + + + + + + + + + +
    关注 <%= link_to User.watched_by(@user.id).count, home_path %> ç²‰ä¸ <%= link_to @user.watcher_users.count, home_path %>
    <%= link_to image_tag(avatar_image(@user), :class => 'avatar'), :class => "avatar" %>
    <% unless User.current == @user %> + <%= watcher_link(@user, User.current) %><% end %>
    +
    + + + +
    +
    +
      +
    • +

      <%= h @user.name %>

      +
    • +
    • +

      <%= mail_to(h(@user.mail), nil, :encode => 'javascript') %>

      +
    • +
    • + <%= l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %> +
    • +
    • + 贡献指数: +
    • +
    +
    + +
    +
    + +
    +
    +
    +

    <%= link_to l(:label_user_watcher), home_path %>

    +
    +
    +
    +
    +
      +
    • +
    • +
    +
    +
    +
    + + + <% unless User.current == @user %> +
    + <%= render :partial => 'words/new', :locals => {:user => @user, :sta => @state}%> +
    + <% end %> + + +
    + +
    + <%= render :partial => 'layouts/tag', :locals => {:obj => @user,:object_flag => "1"}%> +
    +
    +
    + + + +
    + <%= render :partial => 'words/message', :locals => {:message => @message, :state => @state} %> +
    + + +
    +   + +
    +
    +

    <%= link_to l(:label_project_plural),home_path %>

    +
    + <% unless @memberships.empty? %> + +
      + <% for membership in @memberships %> +
    • + + + + + + + + + +
      + +
      +
      + <%= link_to_project(membership.project) %> +
      +
      + <%= membership.project.description%> +
      +
      + <%= l(:label_user_watcher)%><%= link_to"999",home_path%> <%= l(:label_user_commits)%><%= link_to"12",home_path%> +
      +
      + ( + <%= format_date(membership.created_on) %>) +
      +
      +
    • + <% end %> +
    +
    + <%= link_to"更多",:controller=>'projects',:action=>'index'%> +
    + <% else %> + 暂无项目,赶快去<%= link_to"新建",:controller=>'projects',:action=>'new'%>å§ + <% end %> + <%= call_hook :view_account_left_bottom, :user => @user %> +
    + +   + + +************************** +<% unless @memberships.empty? %> +
      + <% for membership in @memberships %> +
    • + + + + + +
      + + + + + + + + + + +
      <%= link_to_project(membership.project) %> 创建了 <%= link_to_project(membership.project) %>

      <%= membership.project.description%>

      <%= format_date(membership.created_on) %><%= link_to"查看其他评论",news_path(news)%><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %>
    • + <% end %> +
    +
    + <%= link_to"更多",:controller=>'projects',:action=>'index'%> +
    + <% else %> + 暂无项目,赶快去<%= link_to"新建",:controller=>'projects',:action=>'new'%>å§ + <% end %> + <%= call_hook :view_account_left_bottom, :user => @user %> + +*************************** + + + + + + + +
    +
    + + + + +

    <%= link_to l(:label_user_newfeedback), home_path %>

    start a...
    +
    +
    + +
      +
    • + + + + + +
      +
      + <%= link_to "huang",home_path%>对我评价了:  +
      +
      + 新建问题的时候存在一个bug,需è¦è§£å†³å¡æ¶µç›–çš„åžƒåœ¾å¡æ‹‰æ ¼å¾·å›½çš„è¨å˜Ž... +
       
      +
    • +
    +
    +
    + <%= link_to"更多",:contoller=>'project',:action=>'index'%> +
    + + +
    +
    +

    <%= link_to l(:label_activity), :controller => 'activities', + :action => 'index', :id => nil, :user_id => @user, + :from => @events_by_day.keys.first %>

    +
    +
    + + +
    + <% @events_by_day.keys.sort.reverse.each do |day| %> + +
      + <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%> +
    • + + + + + + + +
      +
      + <%= content_tag('span', h(e.project), :class => 'project') %> +
      +
      + <%= link_to format_activity_title(e.event_title), e.event_url %> + <%= format_activity_description(e.event_description) %> +
      +
    • + <% end -%> +
    + <% end -%> +
    + + + <% 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 %> + +
    +
    +<% html_title @user.name %> + + + + diff --git a/app/views/users/tag_save.js.erb b/app/views/users/tag_save.js.erb new file mode 100644 index 000000000..da977c144 --- /dev/null +++ b/app/views/users/tag_save.js.erb @@ -0,0 +1,4 @@ +$('#tags_show').html('<%= escape_javascript(render :partial => 'layouts/tag_name',:locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +$('#put-tag-form').hide(); +$('#name').val(""); + diff --git a/app/views/users/user_activities.html.erb b/app/views/users/user_activities.html.erb new file mode 100644 index 000000000..c70896dc8 --- /dev/null +++ b/app/views/users/user_activities.html.erb @@ -0,0 +1,45 @@ + + + +<% unless @events_by_day.empty? %> +
    +<% @events_by_day.keys.sort.reverse.each do |day| %> +<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%> + + + + + + <% end %> +
    + + + + + + + + + + + +
    <%= content_tag('span', h(e.project), :class => 'project') %> æœ‰äº†æœ€æ–°åŠ¨æ€ <%= link_to format_activity_title(e.event_title), e.event_url %>

    <%= format_activity_description(e.event_description) %>

    <%= format_activity_day(day) %>
    <% end %> +
    +<% end %> diff --git a/app/views/users/user_comments.html.erb b/app/views/users/user_comments.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/users/user_newfeedback.html.erb b/app/views/users/user_newfeedback.html.erb new file mode 100644 index 000000000..e29793884 --- /dev/null +++ b/app/views/users/user_newfeedback.html.erb @@ -0,0 +1,8 @@ +
    +
    + <%= render :partial => 'words/message', :locals => {:jour => @jour, :state => @state, :user => @user} %> +
    +
    + <%= render :partial => 'words/new', :locals => {:user => @user, :sta => @state} %> +
    + \ No newline at end of file diff --git a/app/views/users/user_projects.html.erb b/app/views/users/user_projects.html.erb new file mode 100644 index 000000000..b7e0ad2f5 --- /dev/null +++ b/app/views/users/user_projects.html.erb @@ -0,0 +1,39 @@ +
    +<% unless @memberships.empty? %> +
      + <% for membership in @memberships %> +
    • + + + + + + +
      + + + + + + + + + + + +
      <%= link_to_project(membership.project) %>创建了 <%= link_to_project(membership.project) %>
      +

      + <%= membership.project.description%> +

      <%= format_date(membership.created_on) %><%= h membership.roles.sort.collect(&:to_s).join(', ') %>
      + +
    • + <% end %> +
    + +
    + <%= link_to"更多",:controller=>'projects',:action=>'index'%> +
    +<% else %> +暂无项目,赶快去<%= link_to"新建",:controller=>'projects',:action=>'new'%>å§ +<% end %> +<%= call_hook :view_account_left_bottom, :user => @user %>
    \ No newline at end of file diff --git a/app/views/versions/_form.html.erb b/app/views/versions/_form.html.erb new file mode 100644 index 000000000..db84f07eb --- /dev/null +++ b/app/views/versions/_form.html.erb @@ -0,0 +1,16 @@ +<%= back_url_hidden_field_tag %> +<%= error_messages_for 'version' %> + +
    +

    <%= f.text_field :name, :size => 60, :required => true %>

    +

    <%= f.text_field :description, :size => 60 %>

    +

    <%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %>

    +

    <%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %>

    +

    <%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %>

    +

    <%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %>

    + +<% @version.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :version, value %>

    +<% end %> + +
    diff --git a/app/views/versions/_issue_counts.html.erb b/app/views/versions/_issue_counts.html.erb new file mode 100644 index 000000000..002be4938 --- /dev/null +++ b/app/views/versions/_issue_counts.html.erb @@ -0,0 +1,33 @@ +<%= form_tag({}, :id => "status_by_form") do -%> +
    + +<%= l(:label_issues_by, + select_tag('status_by', + status_by_options_for_select(criteria), + :id => 'status_by_select', + :data => {:remote => true, :method => 'post', :url => status_by_version_path(version)})).html_safe %> + +<% if counts.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> + + <% counts.each do |count| %> + + + + + <% end %> +
    + <% if count[:group] -%> + <%= link_to(h(count[:group]), project_issues_path(version.project, :set_filter => 1, :status_id => '*', :fixed_version_id => version, "#{criteria}_id" => count[:group])) %> + <% else -%> + <%= link_to(l(:label_none), project_issues_path(version.project, :set_filter => 1, :status_id => '*', :fixed_version_id => version, "#{criteria}_id" => "!*")) %> + <% end %> + + <%= progress_bar((count[:closed].to_f / count[:total])*100, + :legend => "#{count[:closed]}/#{count[:total]}", + :width => "#{(count[:total].to_f / max * 200).floor}px;") %> +
    +<% end %> +
    +<% end %> diff --git a/app/views/versions/_new_modal.html.erb b/app/views/versions/_new_modal.html.erb new file mode 100644 index 000000000..99fef84e5 --- /dev/null +++ b/app/views/versions/_new_modal.html.erb @@ -0,0 +1,9 @@ +

    <%=l(:label_version_new)%>

    + +<%= labelled_form_for @version, :url => project_versions_path(@project), :remote => true do |f| %> +<%= render :partial => 'versions/form', :locals => { :f => f } %> +

    + <%= submit_tag l(:button_create), :name => nil %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

    +<% end %> diff --git a/app/views/versions/_overview.html.erb b/app/views/versions/_overview.html.erb new file mode 100644 index 000000000..4203a8463 --- /dev/null +++ b/app/views/versions/_overview.html.erb @@ -0,0 +1,32 @@ +<% if version.completed? %> +

    <%= format_date(version.effective_date) %>

    +<% elsif version.effective_date %> +

    <%= due_date_distance_in_words(version.effective_date) %> (<%= format_date(version.effective_date) %>)

    +<% end %> + +

    <%=h version.description %>

    +<% if version.custom_field_values.any? %> +
      + <% version.custom_field_values.each do |custom_value| %> + <% if custom_value.value.present? %> +
    • <%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %>
    • + <% end %> + <% end %> +
    +<% end %> + +<% if version.issues_count > 0 %> + <%= progress_bar([version.closed_percent, version.completed_percent], :width => '40em', :legend => ('%0.0f%' % version.completed_percent)) %> +

    + <%= link_to(l(:label_x_issues, :count => version.issues_count), + project_issues_path(version.project, :status_id => '*', :fixed_version_id => version, :set_filter => 1)) %> +   + (<%= 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)) %> + — + <%= 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)) %>) +

    +<% else %> +

    <%= l(:label_roadmap_no_issues) %>

    +<% end %> diff --git a/app/views/versions/create.js.erb b/app/views/versions/create.js.erb new file mode 100644 index 000000000..e6e0bec45 --- /dev/null +++ b/app/views/versions/create.js.erb @@ -0,0 +1,3 @@ +hideModal(); +<% select = content_tag('select', content_tag('option') + version_options_for_select(@project.shared_versions.open, @version), :id => 'issue_fixed_version_id', :name => 'issue[fixed_version_id]') %> +$('#issue_fixed_version_id').replaceWith('<%= escape_javascript(select) %>'); diff --git a/app/views/versions/edit.html.erb b/app/views/versions/edit.html.erb new file mode 100644 index 000000000..39db07c9d --- /dev/null +++ b/app/views/versions/edit.html.erb @@ -0,0 +1,7 @@ +

    <%=l(:label_version)%>

    + +<%= labelled_form_for @version do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<% end %> + diff --git a/app/views/versions/index.api.rsb b/app/views/versions/index.api.rsb new file mode 100644 index 000000000..3adde2b98 --- /dev/null +++ b/app/views/versions/index.api.rsb @@ -0,0 +1,19 @@ +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 + api.sharing version.sharing + + 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 --git a/app/views/versions/index.html.erb b/app/views/versions/index.html.erb new file mode 100644 index 000000000..e1b29fa99 --- /dev/null +++ b/app/views/versions/index.html.erb @@ -0,0 +1,68 @@ +
    + <%= link_to l(:label_version_new), new_project_version_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %> +
    + +

    <%=l(:label_roadmap)%>

    + +<% if @versions.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> +
    +<% @versions.each do |version| %> +

    <%= link_to_version version, :name => version_anchor(version) %>

    + <%= 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 -%> + + + <% issues.each do |issue| -%> + + + + + <% end -%> + + <% end %> + <% end %> + <%= call_hook :view_projects_roadmap_version_bottom, :version => version %> +<% end %> +
    +<% end %> + +<% content_for :sidebar do %> +<%= form_tag({}, :method => :get) do %> +

    <%= l(:label_roadmap) %>

    +<% @trackers.each do |tracker| %> +
    +<% end %> +
    + +<% if @project.descendants.active.any? %> + <%= hidden_field_tag 'with_subprojects', 0 %> +
    +<% end %> +

    <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %>

    +<% end %> + +

    <%= l(:label_version_plural) %>

    +<% @versions.each do |version| %> +<%= link_to format_version_name(version), "##{version_anchor(version)}" %>
    +<% end %> +<% if @completed_versions.present? %> +

    + <%= link_to_function l(:label_completed_versions), + '$("#toggle-completed-versions").toggleClass("collapsed"); $("#completed-versions").toggle()', + :id => 'toggle-completed-versions', :class => 'collapsible collapsed' %>
    + +

    +<% end %> +<% end %> + +<% html_title(l(:label_roadmap)) %> + +<%= context_menu issues_context_menu_path %> diff --git a/app/views/versions/new.html.erb b/app/views/versions/new.html.erb new file mode 100644 index 000000000..a4b6a1144 --- /dev/null +++ b/app/views/versions/new.html.erb @@ -0,0 +1,6 @@ +

    <%=l(:label_version_new)%>

    + +<%= labelled_form_for @version, :url => project_versions_path(@project) do |f| %> +<%= render :partial => 'versions/form', :locals => { :f => f } %> +<%= submit_tag l(:button_create) %> +<% end %> diff --git a/app/views/versions/new.js.erb b/app/views/versions/new.js.erb new file mode 100644 index 000000000..114b9c7c5 --- /dev/null +++ b/app/views/versions/new.js.erb @@ -0,0 +1,2 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'versions/new_modal') %>'); +showModal('ajax-modal', '600px'); diff --git a/app/views/versions/show.api.rsb b/app/views/versions/show.api.rsb new file mode 100644 index 000000000..63bf2d379 --- /dev/null +++ b/app/views/versions/show.api.rsb @@ -0,0 +1,15 @@ +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 + api.sharing @version.sharing + + render_api_custom_values @version.custom_field_values, api + + api.created_on @version.created_on + api.updated_on @version.updated_on +end diff --git a/app/views/versions/show.html.erb b/app/views/versions/show.html.erb new file mode 100644 index 000000000..2a0fdcc18 --- /dev/null +++ b/app/views/versions/show.html.erb @@ -0,0 +1,55 @@ +
    +<%= 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? %> +<%= delete_link version_path(@version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)) if User.current.allowed_to?(:manage_versions, @version.project) %> +<%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %> +
    + +

    <%= h(@version.name) %>

    + +
    +<%= render :partial => 'versions/overview', :locals => {:version => @version} %> +<%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %> + +
    +<% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %> +
    <%= l(:label_time_tracking) %> + + + + + +<% if User.current.allowed_to?(:view_time_entries, @project) %> + + + + +<% end %> +
    <%= l(:field_estimated_hours) %><%= html_hours(l_hours(@version.estimated_hours)) %>
    <%= l(:label_spent_time) %><%= html_hours(l_hours(@version.spent_hours)) %>
    +
    +<% end %> + +
    +<%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %> +
    +
    + +<% if @issues.present? %> +<%= form_tag({}) do -%> + + + <%- @issues.each do |issue| -%> + + + + + <% end %> + +<% end %> +<%= context_menu issues_context_menu_path %> +<% end %> +
    + +<%= call_hook :view_versions_show_bottom, :version => @version %> + +<% html_title @version.name %> diff --git a/app/views/versions/status_by.js.erb b/app/views/versions/status_by.js.erb new file mode 100644 index 000000000..94e01279c --- /dev/null +++ b/app/views/versions/status_by.js.erb @@ -0,0 +1 @@ +$('#status_by').html('<%= escape_javascript(render_issue_status_by(@version, params[:status_by])) %>'); diff --git a/app/views/watchers/_new.html.erb b/app/views/watchers/_new.html.erb new file mode 100644 index 000000000..9fdf79262 --- /dev/null +++ b/app/views/watchers/_new.html.erb @@ -0,0 +1,27 @@ +

    <%= l(:permission_add_issue_watchers) %>

    + +<%= 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 %> + +

    <%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %>

    + <%= 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) }')" %> + +
    + <%= principals_check_box_tags 'watcher[user_ids][]', (watched ? watched.addable_watcher_users : User.active.all(:limit => 100)) %> +
    + +

    + <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

    +<% end %> diff --git a/app/views/watchers/_set_watcher.js.erb b/app/views/watchers/_set_watcher.js.erb new file mode 100644 index 000000000..e5cdc4f3e --- /dev/null +++ b/app/views/watchers/_set_watcher.js.erb @@ -0,0 +1,2 @@ +<% selector = ".#{watcher_css(watched)}" %> +$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript watcher_link(watched, user) %>")}); diff --git a/app/views/watchers/_watchers.html.erb b/app/views/watchers/_watchers.html.erb new file mode 100644 index 000000000..697d0bd8e --- /dev/null +++ b/app/views/watchers/_watchers.html.erb @@ -0,0 +1,12 @@ +<% if User.current.allowed_to?(:add_issue_watchers, @project) %> +
    +<%= link_to l(:button_add), + {:controller => 'watchers', :action => 'new', :object_type => watched.class.name.underscore, :object_id => watched}, + :remote => true, + :method => 'get' %> +
    +<% end %> + +

    <%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)

    + +<%= watchers_list(watched) %> diff --git a/app/views/watchers/append.js.erb b/app/views/watchers/append.js.erb new file mode 100644 index 000000000..934865dfb --- /dev/null +++ b/app/views/watchers/append.js.erb @@ -0,0 +1,4 @@ +<% @users.each do |user| %> + $("#issue_watcher_user_ids_<%= user.id %>").remove(); +<% end %> +$('#watchers_inputs').append('<%= escape_javascript(watchers_checkboxes(nil, @users, true)) %>'); diff --git a/app/views/watchers/autocomplete_for_user.html.erb b/app/views/watchers/autocomplete_for_user.html.erb new file mode 100644 index 000000000..a24d28eb4 --- /dev/null +++ b/app/views/watchers/autocomplete_for_user.html.erb @@ -0,0 +1 @@ +<%= principals_check_box_tags 'watcher[user_ids][]', @users %> diff --git a/app/views/watchers/create.js.erb b/app/views/watchers/create.js.erb new file mode 100644 index 000000000..0f7e15a00 --- /dev/null +++ b/app/views/watchers/create.js.erb @@ -0,0 +1,2 @@ +$('#ajax-modal').html('<%= escape_javascript(render(:partial => 'watchers/new', :locals => {:watched => @watched})) %>'); +$('#watchers').html('<%= escape_javascript(render(:partial => 'watchers/watchers', :locals => {:watched => @watched})) %>'); diff --git a/app/views/watchers/destroy.js.erb b/app/views/watchers/destroy.js.erb new file mode 100644 index 000000000..e4d856549 --- /dev/null +++ b/app/views/watchers/destroy.js.erb @@ -0,0 +1 @@ +$('#watchers').html('<%= escape_javascript(render(:partial => 'watchers/watchers', :locals => {:watched => @watched})) %>'); diff --git a/app/views/watchers/new.js.erb b/app/views/watchers/new.js.erb new file mode 100644 index 000000000..6b99f657e --- /dev/null +++ b/app/views/watchers/new.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'watchers/new', :locals => {:watched => @watched}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-watcher'); diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb new file mode 100644 index 000000000..59f356d9b --- /dev/null +++ b/app/views/welcome/index.html.erb @@ -0,0 +1,69 @@ +
    + + + + +
    + <%= call_hook :view_account_login_top %> +
    + <%= form_tag(signin_path) do %> + <%= back_url_hidden_field_tag %> + + + + + + + + + + <% if Setting.openid? %> + + + + + <% end %> + + + + + + + + +
    <%= text_field_tag 'username', params[:username], :tabindex => '1' %>
    <%= password_field_tag 'password', nil, :tabindex => '2' %>
    <%= text_field_tag "openid_url", nil, :tabindex => '3' %>
    + <% if Setting.autologin? %> + + <% end %> +
    + <% if Setting.lost_password? %> + <%= link_to l(:label_password_lost), lost_password_path %> + <% end %> + + +
    +<% end %> +
    +<%= call_hook :view_account_login_bottom %> + +<% if params[:username].present? %> +<%= javascript_tag "$('#password').focus();" %> +<% else %> +<%= javascript_tag "$('#username').focus();" %> +<% end %> + +
    + + + + + + +
    +

    <%=link_to "å‘布需求",home_path %>

    +
    +

    <%=link_to "å‘现开æº",home_path %>

    +
    +

    <%=link_to "创建项目",:controller=>'projects',:action=>'index' %>

    +
    +
    diff --git a/app/views/welcome/robots.html.erb b/app/views/welcome/robots.html.erb new file mode 100644 index 000000000..10b540935 --- /dev/null +++ b/app/views/welcome/robots.html.erb @@ -0,0 +1,10 @@ +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 +Disallow: /search diff --git a/app/views/wiki/_content.html.erb b/app/views/wiki/_content.html.erb new file mode 100644 index 000000000..60b6a7452 --- /dev/null +++ b/app/views/wiki/_content.html.erb @@ -0,0 +1,4 @@ +
    + <%= textilizable content, :text, :attachments => content.page.attachments, + :edit_section_links => (@sections_editable && {:controller => 'wiki', :action => 'edit', :project_id => @page.project, :id => @page.title}) %> +
    diff --git a/app/views/wiki/_sidebar.html.erb b/app/views/wiki/_sidebar.html.erb new file mode 100644 index 000000000..b4034d88b --- /dev/null +++ b/app/views/wiki/_sidebar.html.erb @@ -0,0 +1,9 @@ +<% if @wiki && @wiki.sidebar -%> + <%= textilizable @wiki.sidebar.content, :text %> +<% end -%> + +

    <%= l(:label_wiki) %>

    + +<%= link_to l(:field_start_page), {:action => 'show', :id => nil} %>
    +<%= link_to l(:label_index_by_title), {:action => 'index'} %>
    +<%= link_to l(:label_index_by_date), {:controller => 'wiki', :project_id => @project, :action => 'date_index'} %>
    diff --git a/app/views/wiki/annotate.html.erb b/app/views/wiki/annotate.html.erb new file mode 100644 index 000000000..e3c2acd0c --- /dev/null +++ b/app/views/wiki/annotate.html.erb @@ -0,0 +1,41 @@ +
    +<%= link_to(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit') %> +<%= link_to(l(:label_history), + {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %> +
    + +<%= wiki_page_breadcrumb(@page) %> + +

    <%=h @page.pretty_title %>

    + +

    +<%= l(:label_version) %> <%= link_to h(@annotate.content.version), + :action => 'show', :project_id => @project, + :id => @page.title, :version => @annotate.content.version %> +(<%= h(@annotate.content.author ? + @annotate.content.author.name : l(:label_user_anonymous)) + %>, <%= format_time(@annotate.content.updated_on) %>) +

    + +<% colors = Hash.new {|k,v| k[v] = (k.size % 12) } %> + + + +<% line_num = 1 %> +<% @annotate.lines.each do |line| -%> + + + + + + +<% line_num += 1 %> +<% end -%> + +
    <%= line_num %><%= link_to line[0], :controller => 'wiki', + :action => 'show', :project_id => @project, + :id => @page.title, :version => line[0] %><%= h(line[1]) %>
    <%=h line[2] %>
    + +<% content_for :header_tags do %> +<%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/wiki/date_index.html.erb b/app/views/wiki/date_index.html.erb new file mode 100644 index 000000000..708e122c7 --- /dev/null +++ b/app/views/wiki/date_index.html.erb @@ -0,0 +1,36 @@ +
    +<%= watcher_link(@wiki, User.current) %> +
    + +

    <%= l(:label_index_by_date) %>

    + +<% if @pages.empty? %> +

    <%= l(:label_no_data) %>

    +<% end %> + +<% @pages_by_date.keys.sort.reverse.each do |date| %> +

    <%= format_date(date) %>

    +
      +<% @pages_by_date[date].each do |page| %> +
    • <%= link_to h(page.pretty_title), :action => 'show', :id => page.title, :project_id => page.project %>
    • +<% end %> +
    +<% 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 --git a/app/views/wiki/destroy.html.erb b/app/views/wiki/destroy.html.erb new file mode 100644 index 000000000..6fb199804 --- /dev/null +++ b/app/views/wiki/destroy.html.erb @@ -0,0 +1,22 @@ +<%= wiki_page_breadcrumb(@page) %> + +

    <%=h @page.pretty_title %>

    + +<%= form_tag({}, :method => :delete) do %> +
    +

    <%= l(:text_wiki_page_destroy_question, :descendants => @descendants_count) %>

    +


    + +<% if @reassignable_to.any? %> +
    +: +<%= 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').attr('checked', true);" %> +<% end %> +

    +
    + +<%= submit_tag l(:button_apply) %> +<%= link_to l(:button_cancel), :controller => 'wiki', :action => 'show', :project_id => @project, :id => @page.title %> +<% end %> diff --git a/app/views/wiki/diff.html.erb b/app/views/wiki/diff.html.erb new file mode 100644 index 000000000..c1062924c --- /dev/null +++ b/app/views/wiki/diff.html.erb @@ -0,0 +1,27 @@ +
    +<%= link_to(l(:label_history), {:action => 'history', :id => @page.title}, + :class => 'icon icon-history') %> +
    + +<%= wiki_page_breadcrumb(@page) %> + +

    <%= h(@page.pretty_title) %>

    + +

    +<%= l(:label_version) %> <%= link_to @diff.content_from.version, :action => 'show', :id => @page.title, :project_id => @page.project, :version => @diff.content_from.version %> +(<%= @diff.content_from.author ? + @diff.content_from.author.name : l(:label_user_anonymous) + %>, <%= format_time(@diff.content_from.updated_on) %>) +→ +<%= l(:label_version) %> <%= link_to @diff.content_to.version, :action => 'show', + :id => @page.title, :project_id => @page.project, + :version => @diff.content_to.version + %>/<%= @page.content.version %> +(<%= @diff.content_to.author ? + link_to_user(@diff.content_to.author.name) : l(:label_user_anonymous) + %>, <%= format_time(@diff.content_to.updated_on) %>) +

    + +
    +<%= simple_format_without_paragraph @diff.to_html %> +
    diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb new file mode 100644 index 000000000..14b863f53 --- /dev/null +++ b/app/views/wiki/edit.html.erb @@ -0,0 +1,46 @@ +<%= wiki_page_breadcrumb(@page) %> + +

    <%= h @page.pretty_title %>

    + +<%= form_for @content, :as => :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' %> + +
    +<%= text_area_tag 'content[text]', @text, :cols => 100, :rows => 25, + :class => 'wiki-edit', :accesskey => accesskey(:edit) %> + +<% if @page.safe_attribute_names.include?('parent_id') && @wiki.pages.any? %> + <%= fields_for @page do |fp| %> +

    + + <%= fp.select :parent_id, + content_tag('option', '', :value => '') + + wiki_page_options_for_select(@wiki.pages.all(:include => :parent) - + @page.self_and_descendants, @page.parent) %> +

    + <% end %> +<% end %> + +

    <%= f.text_field :comments, :size => 120 %>

    +

    <%= render :partial => 'attachments/form' %>

    +
    + +

    <%= submit_tag l(:button_save) %> + <%= preview_link({:controller => 'wiki', :action => 'preview', :project_id => @project, :id => @page.title }, 'wiki_form') %>

    +<%= wikitoolbar_for 'content_text' %> +<% end %> + +
    + +<% content_for :header_tags do %> + <%= robot_exclusion_tag %> +<% end %> + +<% html_title @page.pretty_title %> diff --git a/app/views/wiki/export.html.erb b/app/views/wiki/export.html.erb new file mode 100644 index 000000000..7e8d072d5 --- /dev/null +++ b/app/views/wiki/export.html.erb @@ -0,0 +1,21 @@ + + + +<%=h @page.pretty_title %> + + + + +<%= textilizable @content, :text, :wiki_links => :local %> + + diff --git a/app/views/wiki/export_multiple.html.erb b/app/views/wiki/export_multiple.html.erb new file mode 100644 index 000000000..24b1ad3ec --- /dev/null +++ b/app/views/wiki/export_multiple.html.erb @@ -0,0 +1,34 @@ + + + +<%=h @wiki.project.name %> + + + + + +<%= l(:label_index_by_title) %> + + +<% @pages.each do |page| %> +
    + +<%= textilizable page.content ,:text, :wiki_links => :anchor %> +<% end %> + + + diff --git a/app/views/wiki/history.html.erb b/app/views/wiki/history.html.erb new file mode 100644 index 000000000..17cb19118 --- /dev/null +++ b/app/views/wiki/history.html.erb @@ -0,0 +1,42 @@ +<%= wiki_page_breadcrumb(@page) %> + +

    <%= h(@page.pretty_title) %>

    + +

    <%= l(:label_history) %>

    + +<%= form_tag({:controller => 'wiki', :action => 'diff', + :project_id => @page.project, :id => @page.title}, + :method => :get) do %> + + + + + + + + + + + +<% show_diff = @versions.size > 1 %> +<% line_num = 1 %> +<% @versions.each do |ver| %> +"> + + + + + + + + +<% line_num += 1 %> +<% end %> + +
    #<%= l(:field_updated_on) %><%= l(:field_author) %><%= l(:field_comments) %>
    <%= link_to h(ver.version), :action => 'show', :id => @page.title, :project_id => @page.project, :version => ver.version %><%= radio_button_tag('version', ver.version, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('#cbto-#{line_num+1}').attr('checked', true);") if show_diff && (line_num < @versions.size) %><%= radio_button_tag('version_from', ver.version, (line_num==2), :id => "cbto-#{line_num}") if show_diff && (line_num > 1) %><%= format_time(ver.updated_on) %><%= link_to_user ver.author %><%=h ver.comments %> + <%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %> + <%= delete_link wiki_page_path(@page, :version => ver.version) if User.current.allowed_to?(:delete_wiki_pages, @page.project) && @version_count > 1 %> +
    +<%= submit_tag l(:label_view_diff), :class => 'small' if show_diff %> +<%= pagination_links_full @version_pages, @version_count %> +<% end %> diff --git a/app/views/wiki/index.api.rsb b/app/views/wiki/index.api.rsb new file mode 100644 index 000000000..f1035c89b --- /dev/null +++ b/app/views/wiki/index.api.rsb @@ -0,0 +1,13 @@ +api.array :wiki_pages do + @pages.each do |page| + api.wiki_page do + api.title page.title + if page.parent + api.parent :title => page.parent.title + end + api.version page.version + api.created_on page.created_on + api.updated_on page.updated_on + end + end +end diff --git a/app/views/wiki/index.html.erb b/app/views/wiki/index.html.erb new file mode 100644 index 000000000..463c6be97 --- /dev/null +++ b/app/views/wiki/index.html.erb @@ -0,0 +1,35 @@ +
    +<%= watcher_link(@wiki, User.current) %> +
    + +

    <%= l(:label_index_by_title) %>

    + +<% if @pages.empty? %> +

    <%= l(:label_no_data) %>

    +<% 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 --git a/app/views/wiki/rename.html.erb b/app/views/wiki/rename.html.erb new file mode 100644 index 000000000..ee0e49594 --- /dev/null +++ b/app/views/wiki/rename.html.erb @@ -0,0 +1,21 @@ +<%= wiki_page_breadcrumb(@page) %> + +

    <%= h @original_title %>

    + +<%= error_messages_for 'page' %> + +<%= labelled_form_for :wiki_page, @page, + :url => { :action => 'rename' }, + :html => { :method => :post } do |f| %> +
    +

    <%= f.text_field :title, :required => true, :size => 100 %>

    +

    <%= f.check_box :redirect_existing_links %>

    +

    <%= f.select :parent_id, + content_tag('option', '', :value => '') + + wiki_page_options_for_select( + @wiki.pages.all(:include => :parent) - @page.self_and_descendants, + @page.parent), + :label => :field_parent_title %>

    +
    +<%= submit_tag l(:button_rename) %> +<% end %> diff --git a/app/views/wiki/show.api.rsb b/app/views/wiki/show.api.rsb new file mode 100644 index 000000000..c35316104 --- /dev/null +++ b/app/views/wiki/show.api.rsb @@ -0,0 +1,18 @@ +api.wiki_page do + api.title @page.title + if @page.parent + api.parent :title => @page.parent.title + end + api.text @content.text + api.version @content.version + api.author(:id => @content.author_id, :name => @content.author.name) + api.comments @page.content.comments + api.created_on @page.created_on + api.updated_on @content.updated_on + + api.array :attachments do + @page.attachments.each do |attachment| + render_api_attachment(attachment, api) + end + end if include_in_api_response?('attachments') +end diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb new file mode 100644 index 000000000..b4386b754 --- /dev/null +++ b/app/views/wiki/show.html.erb @@ -0,0 +1,71 @@ +
    +<% 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') %> +
    + +<%= wiki_page_breadcrumb(@page) %> + +<% unless @content.current_version? %> +

    + <%= 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) %> +
    + <%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous) + %>, <%= format_time(@content.updated_on) %>
    + <%=h @content.comments %> +

    +
    +<% end %> + +<%= render(:partial => "wiki/content", :locals => {:content => @content}) %> + +<%= link_to_attachments @page %> + +<% if @editable && authorize_for('wiki', 'add_attachment') %> +
    +

    <%= link_to l(:label_attachment_new), {}, :onclick => "$('#add_attachment_form').show(); return false;", + :id => 'attach_files_link' %>

    +<%= form_tag({:controller => 'wiki', :action => 'add_attachment', + :project_id => @project, :id => @page.title}, + :multipart => true, :id => "add_attachment_form", + :style => "display:none;") do %> +
    +

    <%= render :partial => 'attachments/form' %>

    +
    +<%= submit_tag l(:button_add) %> +<%= link_to l(:button_cancel), {}, :onclick => "$('#add_attachment_form').hide(); return false;" %> +<% end %> +
    +<% 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 --git a/app/views/wikis/destroy.html.erb b/app/views/wikis/destroy.html.erb new file mode 100644 index 000000000..04988d863 --- /dev/null +++ b/app/views/wikis/destroy.html.erb @@ -0,0 +1,10 @@ +

    <%=l(:label_confirmation)%>

    + +
    +

    <%= h(@project.name) %>
    <%=l(:text_wiki_destroy_confirmation)%>

    + +<%= form_tag({:controller => 'wikis', :action => 'destroy', :id => @project}) do %> +<%= hidden_field_tag "confirm", 1 %> +<%= submit_tag l(:button_delete) %> +<% end %> +
    diff --git a/app/views/wikis/edit.js.erb b/app/views/wikis/edit.js.erb new file mode 100644 index 000000000..2c765d156 --- /dev/null +++ b/app/views/wikis/edit.js.erb @@ -0,0 +1 @@ +$('#tab-content-wiki').html('<%= escape_javascript(render :partial => 'projects/settings/wiki') %>'); diff --git a/app/views/words/_message.html.erb b/app/views/words/_message.html.erb new file mode 100644 index 000000000..85d30c884 --- /dev/null +++ b/app/views/words/_message.html.erb @@ -0,0 +1,26 @@ +<% if jour.size >0 %> +<% remove_allowed = (User.current.id == jour.first.user_id) %> +<% for journal in jour%> + + + + + +
    + + + + + + + + + + +
    <%=link_to journal.user, user_path(journal.user)%> 给我留言了

    <%= textilizable journal.notes%>

    <%= journal.created_at %><%= link_to(image_tag('comment.png'), {:controller => 'words', :action => 'new', :id => user, :journal_id => journal}, :remote => true, + :method => 'post', :title => l(:button_quote))%><%= link_to(image_tag('delete.png'), {:controller => 'words', :action => 'destroy', :object_id => journal, :user_id => user}, + :remote => true, :method => 'delete', :class => "delete", :title => l(:button_delete)) if remove_allowed || journal.jour_id == User.current.id %>
    +<% end %> +<% end %> + + diff --git a/app/views/words/_new.html.erb b/app/views/words/_new.html.erb new file mode 100644 index 000000000..925ebefa8 --- /dev/null +++ b/app/views/words/_new.html.erb @@ -0,0 +1,13 @@ +

    <%= l(:label_leave_message_to, :name => "user") %>

    + +<%= form_for("new_form", :remote => true, :url => {:controller => 'words', + :action => 'create', + :user_id => user.id, + :sta => sta}) do |f| %> + +

    <%= label_tag 'user_message', l(:label_leave_message) %><%= f.text_area 'user_message', :rows => 3 %>

    +

    + <%= submit_tag l(:button_leave_meassge), :name => nil %> + <%= submit_tag l(:button_clear), :name => nil, :onclick => "clearMessage('user_message');", :type => 'button' %> +

    +<% end %> diff --git a/app/views/words/back.js.erb b/app/views/words/back.js.erb new file mode 100644 index 000000000..17c8aa9be --- /dev/null +++ b/app/views/words/back.js.erb @@ -0,0 +1 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'words/message', :locals => {:jour => @jour, :state => @state, :user => @user})) %>'); diff --git a/app/views/words/create.js.erb b/app/views/words/create.js.erb new file mode 100644 index 000000000..fa0798a5a --- /dev/null +++ b/app/views/words/create.js.erb @@ -0,0 +1,2 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'words/message', :locals => {:jour => @jour, :state => false, :user => @user})) %>'); +$('#new_form_user_message').val(""); \ No newline at end of file diff --git a/app/views/words/destroy.js.erb b/app/views/words/destroy.js.erb new file mode 100644 index 000000000..d1eeb4d5f --- /dev/null +++ b/app/views/words/destroy.js.erb @@ -0,0 +1 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'words/message', :locals => {:jour => @jour, :state => false, :user => @user})) %>'); diff --git a/app/views/words/more.js.erb b/app/views/words/more.js.erb new file mode 100644 index 000000000..17c8aa9be --- /dev/null +++ b/app/views/words/more.js.erb @@ -0,0 +1 @@ +$('#message').html('<%= escape_javascript(render(:partial => 'words/message', :locals => {:jour => @jour, :state => @state, :user => @user})) %>'); diff --git a/app/views/words/new.js.erb b/app/views/words/new.js.erb new file mode 100644 index 000000000..16fabe66f --- /dev/null +++ b/app/views/words/new.js.erb @@ -0,0 +1,2 @@ +$('#new_form_user_message').val("<%= raw escape_javascript(@content) %>"); +showAndScrollTo("new_form_user_message", "new_form_user_message"); diff --git a/app/views/workflows/_action_menu.html.erb b/app/views/workflows/_action_menu.html.erb new file mode 100644 index 000000000..577281128 --- /dev/null +++ b/app/views/workflows/_action_menu.html.erb @@ -0,0 +1,5 @@ +
    +<%= link_to l(:button_edit), {:action => 'edit'}, :class => 'icon icon-edit' %> +<%= link_to l(:button_copy), {:action => 'copy'}, :class => 'icon icon-copy' %> +<%= link_to l(:field_summary), {:action => 'index'}, :class => 'icon icon-summary' %> +
    diff --git a/app/views/workflows/_form.html.erb b/app/views/workflows/_form.html.erb new file mode 100644 index 000000000..ec015a994 --- /dev/null +++ b/app/views/workflows/_form.html.erb @@ -0,0 +1,41 @@ + + + + + + + + + <% for new_status in @statuses %> + + <% end %> + + + + <% for old_status in @statuses %> + "> + + <% for new_status in @statuses -%> + <% checked = workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id} %> + + <% end -%> + + <% end %> + +
    + <%= 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)%> + <%=l(:label_new_statuses_allowed)%>
    + <%= 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 %> +
    + <%= 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 %> + + <%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, checked, + :class => "old-status-#{old_status.id} new-status-#{new_status.id}" %> +
    diff --git a/app/views/workflows/copy.html.erb b/app/views/workflows/copy.html.erb new file mode 100644 index 000000000..64bb5a55c --- /dev/null +++ b/app/views/workflows/copy.html.erb @@ -0,0 +1,40 @@ +<%= render :partial => 'action_menu' %> + +

    <%=l(:label_workflow)%>

    + +<%= form_tag({}, :id => 'workflow_copy_form') do %> +
    +<%= l(:label_copy_source) %> +

    + + <%= select_tag('source_tracker_id', + content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '') + + content_tag('option', "--- #{ l(:label_copy_same_as_target) } ---", :value => 'any') + + options_from_collection_for_select(@trackers, 'id', 'name', @source_tracker && @source_tracker.id)) %> +

    +

    + + <%= select_tag('source_role_id', + content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '') + + content_tag('option', "--- #{ l(:label_copy_same_as_target) } ---", :value => 'any') + + options_from_collection_for_select(@roles, 'id', 'name', @source_role && @source_role.id)) %> +

    +
    + +
    +<%= l(:label_copy_target) %> +

    + + <%= select_tag 'target_tracker_ids', + content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '', :disabled => true) + + options_from_collection_for_select(@trackers, 'id', 'name', @target_trackers && @target_trackers.map(&:id)), :multiple => true %> +

    +

    + + <%= select_tag 'target_role_ids', + content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '', :disabled => true) + + options_from_collection_for_select(@roles, 'id', 'name', @target_roles && @target_roles.map(&:id)), :multiple => true %> +

    +
    +<%= submit_tag l(:button_copy) %> +<% end %> diff --git a/app/views/workflows/edit.html.erb b/app/views/workflows/edit.html.erb new file mode 100644 index 000000000..9b5e986c8 --- /dev/null +++ b/app/views/workflows/edit.html.erb @@ -0,0 +1,58 @@ +<%= render :partial => 'action_menu' %> + +

    <%=l(:label_workflow)%>

    + +
    +
      +
    • <%= link_to l(:label_status_transitions), {:action => 'edit', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %>
    • +
    • <%= link_to l(:label_fields_permissions), {:action => 'permissions', :role_id => @role, :tracker_id => @tracker} %>
    • +
    +
    + +

    <%=l(:text_workflow_edit)%>:

    + +<%= form_tag({}, :method => 'get') do %> +

    + + + + + <%= submit_tag l(:button_edit), :name => nil %> + + <%= hidden_field_tag 'used_statuses_only', '0' %> + + +

    +<% 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 %> + <%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only] %> +
    + <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %> + +
    + <%= l(:label_additional_workflow_transitions_for_author) %> +
    + <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %> +
    +
    + <%= javascript_tag "hideFieldset($('#author_workflows'))" unless @workflows['author'].present? %> + +
    + <%= l(:label_additional_workflow_transitions_for_assignee) %> +
    + <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %> +
    +
    + <%= javascript_tag "hideFieldset($('#assignee_workflows'))" unless @workflows['assignee'].present? %> +
    + <%= submit_tag l(:button_save) %> + <% end %> +<% end %> + +<% html_title(l(:label_workflow)) -%> diff --git a/app/views/workflows/index.html.erb b/app/views/workflows/index.html.erb new file mode 100644 index 000000000..a15441869 --- /dev/null +++ b/app/views/workflows/index.html.erb @@ -0,0 +1,35 @@ +<%= render :partial => 'action_menu' %> + +

    <%=l(:label_workflow)%>

    + +<% if @workflow_counts.empty? %> +

    <%= l(:label_no_data) %>

    +<% else %> +
    + + + + + <% @workflow_counts.first.last.each do |role, count| %> + + + <% end %> + + + +<% @workflow_counts.each do |tracker, roles| -%> + + + <% roles.each do |role, count| -%> + + <% end -%> + +<% end -%> + +
    + <%= content_tag(role.builtin? ? 'em' : 'span', h(role.name)) %> +
    <%= h tracker %> + <%= link_to((count > 0 ? count : image_tag('false.png')), {:action => 'edit', :role_id => role, :tracker_id => tracker}, :title => l(:button_edit)) %> +
    +
    +<% end %> diff --git a/app/views/workflows/permissions.html.erb b/app/views/workflows/permissions.html.erb new file mode 100644 index 000000000..71339cc1b --- /dev/null +++ b/app/views/workflows/permissions.html.erb @@ -0,0 +1,95 @@ +<%= render :partial => 'action_menu' %> + +

    <%=l(:label_workflow)%>

    + +
    +
      +
    • <%= link_to l(:label_status_transitions), {:action => 'edit', :role_id => @role, :tracker_id => @tracker} %>
    • +
    • <%= link_to l(:label_fields_permissions), {:action => 'permissions', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %>
    • +
    +
    + +

    <%=l(:text_workflow_edit)%>:

    + +<%= form_tag({}, :method => 'get') do %> +

    + + + + + <%= submit_tag l(:button_edit), :name => nil %> + + <%= hidden_field_tag 'used_statuses_only', '0' %> + +

    +<% 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 %> + <%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only] %> +
    + + + + + + + + + <% for status in @statuses %> + + <% end %> + + + + + + + <% @fields.each do |field, name| %> + "> + + <% for status in @statuses -%> + + <% end -%> + + <% end %> + <% if @custom_fields.any? %> + + + + <% @custom_fields.each do |field| %> + "> + + <% for status in @statuses -%> + + <% end -%> + + <% end %> + <% end %> + +
    + <%=l(:label_issue_status)%>
    + <%=h status.name %> +
    +   + <%= l(:field_core_fields) %> +
    + <%=h name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %> + + <%= field_permission_tag(@permissions, status, field) %> +
    +   + <%= l(:label_custom_field_plural) %> +
    + <%=h field.name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %> + + <%= field_permission_tag(@permissions, status, field) %> +
    +
    + <%= submit_tag l(:button_save) %> + <% end %> +<% end %> diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..2a89752d7 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run RedmineApp::Application diff --git a/config/additional_environment.rb b/config/additional_environment.rb new file mode 100644 index 000000000..2a317a396 --- /dev/null +++ b/config/additional_environment.rb @@ -0,0 +1,10 @@ +# 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 +# ... +# + diff --git a/config/additional_environment.rb.example b/config/additional_environment.rb.example new file mode 100644 index 000000000..2a317a396 --- /dev/null +++ b/config/additional_environment.rb.example @@ -0,0 +1,10 @@ +# 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 +# ... +# + diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..e434bd2a3 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,62 @@ +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +if defined?(Bundler) + # If you precompile assets before deploying to production, use this line + Bundler.require(*Rails.groups(:assets => %w(development test))) + # If you want your assets lazily compiled in production, use this line + # Bundler.require(:default, :assets, Rails.env) +end + +module RedmineApp + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Custom directories with classes and modules you want to be autoloadable. + config.autoload_paths += %W(#{config.root}/lib) + + # Only load the plugins named here, in the order given (default is alphabetical). + # :all can be used as a placeholder for all plugins not explicitly named. + # config.plugins = [ :exception_notification, :ssl_requirement, :all ] + + # Activate observers that should always be running. + config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer, :comment_observer + + config.active_record.store_full_sti_class = true + config.active_record.default_timezone = :local + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding = "utf-8" + + # Configure sensitive parameters which will be filtered from the log file. + config.filter_parameters += [:password] + + # Enable the asset pipeline + config.assets.enabled = false + + # Version of your assets, change this if you want to expire all your assets + config.assets.version = '1.0' + + config.action_mailer.perform_deliveries = false + + # Do not include all helpers + config.action_controller.include_all_helpers = false + + config.session_store :cookie_store, :key => '_redmine_session' + + 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 +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..4489e5868 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,6 @@ +require 'rubygems' + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/config/configuration.yml b/config/configuration.yml new file mode 100644 index 000000000..27eb86f68 --- /dev/null +++ b/config/configuration.yml @@ -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 --git a/config/configuration.yml.example b/config/configuration.yml.example new file mode 100644 index 000000000..27eb86f68 --- /dev/null +++ b/config/configuration.yml.example @@ -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 --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..dd814a4eb --- /dev/null +++ b/config/database.yml @@ -0,0 +1,45 @@ +# 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. + +production: + adapter: mysql2 + database: bitnami_redmine + host: 10.0.47.245 + port: 3306 + username: root + password: "bitnami" + encoding: utf8 + +development: + adapter: mysql2 + database: bitnami_redmine + host: 10.0.47.245 + port: 3306 + username: root + password: "bitnami" + 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: bitnami_redmine + host: 10.0.47.121 + port: 3306 + username: root + password: "7a9dca93e6" + encoding: utf8 + +test_pgsql: + adapter: postgresql + database: bitnami_redmine + host: 10.0.47.121 + port: 3306 + username: root + password: "1234" + +test_sqlite3: + adapter: sqlite3 + database: bitnami_redmine diff --git a/config/database.yml.example b/config/database.yml.example new file mode 100644 index 000000000..5bcf17bd6 --- /dev/null +++ b/config/database.yml.example @@ -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 --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..1d9a39669 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,14 @@ +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Make sure there's no plugin in vendor/plugin before starting +vendor_plugins_dir = File.join(Rails.root, "vendor", "plugins") +if Dir.glob(File.join(vendor_plugins_dir, "*")).any? + $stderr.puts "Plugins in vendor/plugins (#{vendor_plugins_dir}) are no longer allowed. " + + "Please, put your Redmine plugins in the `plugins` directory at the root of your " + + "Redmine directory (#{File.join(Rails.root, "plugins")})" + exit 1 +end + +# Initialize the rails application +RedmineApp::Application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..bd92c5552 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,19 @@ +# Settings specified here will take precedence over those in config/application.rb +RedmineApp::Application.configure do + # 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 + + config.active_support.deprecation = :log +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..ab4cd4011 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,32 @@ +# Settings specified here will take precedence over those in config/application.rb +RedmineApp::Application.configure do + # 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.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 + + config.active_support.deprecation = :log +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..b4696385e --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,30 @@ +# Settings specified here will take precedence over those in config/application.rb +RedmineApp::Application.configure do + # 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 + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # 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.active_support.deprecation = :log + + config.secret_token = 'a secret token for running the tests' +end diff --git a/config/environments/test_pgsql.rb b/config/environments/test_pgsql.rb new file mode 100644 index 000000000..45cb09bdd --- /dev/null +++ b/config/environments/test_pgsql.rb @@ -0,0 +1 @@ +instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) diff --git a/config/environments/test_sqlite3.rb b/config/environments/test_sqlite3.rb new file mode 100644 index 000000000..45cb09bdd --- /dev/null +++ b/config/environments/test_sqlite3.rb @@ -0,0 +1 @@ +instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) diff --git a/config/initializers/00-core_plugins.rb b/config/initializers/00-core_plugins.rb new file mode 100644 index 000000000..004c2a1f6 --- /dev/null +++ b/config/initializers/00-core_plugins.rb @@ -0,0 +1,15 @@ +# Loads the core plugins located in lib/plugins +Dir.glob(File.join(Rails.root, "lib/plugins/*")).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) + config = config = RedmineApp::Application.config + eval(File.read(initializer), binding, initializer) + end + end +end diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb new file mode 100644 index 000000000..79641513e --- /dev/null +++ b/config/initializers/10-patches.rb @@ -0,0 +1,167 @@ +require 'active_record' + +module ActiveRecord + class Base + include Redmine::I18n + # Translate attribute names for validation errors display + def self.human_attribute_name(attr, *args) + attr = attr.to_s.sub(/_id$/, '') + + l("field_#{name.underscore.gsub('/', '_')}_#{attr}", :default => ["field_#{attr}".to_sym, attr]) + end + end + + # Undefines private Kernel#open method to allow using `open` scopes in models. + # See Defect #11545 (http://www.redmine.org/issues/11545) for details. + class Base + class << self + undef open + end + end + class Relation ; undef open ; 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 + + class Resolver + def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[]) + cached(key, [name, prefix, partial], details, locals) do + if details[:formats] & [:xml, :json] + details = details.dup + details[:formats] = details[:formats].dup + [:api] + end + find_templates(name, prefix, partial, details) + end + end + end +end + +# Do not HTML escape text templates +module ActionView + class Template + module Handlers + class ERB + def call(template) + if template.source.encoding_aware? + # First, convert to BINARY, so in case the encoding is + # wrong, we can still find an encoding tag + # (<%# encoding %>) inside the String using a regular + # expression + template_source = template.source.dup.force_encoding("BINARY") + + erb = template_source.gsub(ENCODING_TAG, '') + encoding = $2 + + erb.force_encoding valid_encoding(template.source.dup, encoding) + + # Always make sure we return a String in the default_internal + erb.encode! + else + erb = template.source.dup + end + + self.class.erb_implementation.new( + erb, + :trim => (self.class.erb_trim_mode == "-"), + :escape => template.identifier =~ /\.text/ # only escape HTML templates + ).src + end + end + end + end +end + +ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || ''.html_safe } + +require 'mail' + +module DeliveryMethods + class AsyncSMTP < ::Mail::SMTP + def deliver!(*args) + Thread.start do + super *args + end + end + end + + class AsyncSendmail < ::Mail::Sendmail + def deliver!(*args) + Thread.start do + super *args + end + end + end + + class TmpFile + def initialize(*args); end + + def deliver!(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 +end + +ActionMailer::Base.add_delivery_method :async_smtp, DeliveryMethods::AsyncSMTP +ActionMailer::Base.add_delivery_method :async_sendmail, DeliveryMethods::AsyncSendmail +ActionMailer::Base.add_delivery_method :tmp_file, DeliveryMethods::TmpFile + +# Changes how sent emails are logged +# Rails doesn't log cc and bcc which is misleading when using bcc only (#12090) +module ActionMailer + class LogSubscriber < ActiveSupport::LogSubscriber + def deliver(event) + recipients = [:to, :cc, :bcc].inject("") do |s, header| + r = Array.wrap(event.payload[header]) + if r.any? + s << "\n #{header}: #{r.join(', ')}" + end + s + end + info("\nSent email \"#{event.payload[:subject]}\" (%1.fms)#{recipients}" % event.duration) + debug(event.payload[:mail]) + end + end +end + +module ActionController + module MimeResponds + class Collector + def api(&block) + any(:xml, :json, &block) + end + end + end +end + +module ActionController + class Base + # Displays an explicit message instead of a NoMethodError exception + # when trying to start Redmine with an old session_store.rb + # TODO: remove it in a later version + def self.session=(*args) + $stderr.puts "Please remove config/initializers/session_store.rb and run `rake generate_secret_token`.\n" + + "Setting the session secret with ActionController.session= is no longer supported in Rails 3." + exit 1 + end + end +end diff --git a/config/initializers/20-mime_types.rb b/config/initializers/20-mime_types.rb new file mode 100644 index 000000000..cfd35a3e9 --- /dev/null +++ b/config/initializers/20-mime_types.rb @@ -0,0 +1,4 @@ +# Add new mime types for use in respond_to blocks: + +Mime::SET << Mime::CSV unless Mime::SET.include?(Mime::CSV) + diff --git a/config/initializers/30-redmine.rb b/config/initializers/30-redmine.rb new file mode 100644 index 000000000..1018ca18c --- /dev/null +++ b/config/initializers/30-redmine.rb @@ -0,0 +1,15 @@ +I18n.default_locale = 'en' +I18n.backend = Redmine::I18n::Backend.new + +require 'redmine' + +# Load the secret token from the Redmine configuration file +secret = Redmine::Configuration['secret_token'] +if secret.present? + RedmineApp::Application.config.secret_token = secret +end + +Redmine::Plugin.load +unless Redmine::Configuration['mirror_plugins_assets_on_startup'] == false + Redmine::Plugin.mirror_assets +end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..370315de2 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..d531b8bb8 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,10 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format +# (all these examples are active by default): +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb new file mode 100644 index 000000000..68cbf0aea --- /dev/null +++ b/config/initializers/secret_token.rb @@ -0,0 +1,11 @@ +# This file was generated by 'rake generate_secret_token', 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. +RedmineApp::Application.config.secret_token = '8109e793d9c8233f79ebe3aa09c756d54bf6bffe7043ce1c4bd73928864c72a0b323bc3ccc82493e' diff --git a/config/locales/ar.yml b/config/locales/ar.yml new file mode 100644 index 000000000..52e49492b --- /dev/null +++ b/config/locales/ar.yml @@ -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: "1 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/az.yml b/config/locales/az.yml new file mode 100644 index 000000000..901df1976 --- /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 hour" + other: "%{count} hours" + 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 «hazırlıq» 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.
    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.
    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 --git a/config/locales/bg.yml b/config/locales/bg.yml new file mode 100644 index 000000000..78fb6fe32 --- /dev/null +++ b/config/locales/bg.yml @@ -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 hour" + other: "%{count} hours" + 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), цифри, тирета и _.
    ПромÑна Ñлед Ñъздаването му не е възможна.' + 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), цифри, тирета и _.
    ПромÑна Ñлед Ñъздаването му не е възможна.' diff --git a/config/locales/bs.yml b/config/locales/bs.yml new file mode 100644 index 000000000..50f230014 --- /dev/null +++ b/config/locales/bs.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/ca.yml b/config/locales/ca.yml new file mode 100644 index 000000000..f9e6a40fc --- /dev/null +++ b/config/locales/ca.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/cs.yml b/config/locales/cs.yml new file mode 100644 index 000000000..81870f83d --- /dev/null +++ b/config/locales/cs.yml @@ -0,0 +1,1093 @@ +# Update to 2.2 by Karel Picman +# Update to 1.1 by Michal Gebauer +# Updated by Josef LiÅ¡ka +# 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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/da.yml b/config/locales/da.yml new file mode 100644 index 000000000..48a94fec7 --- /dev/null +++ b/config/locales/da.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/de.yml b/config/locales/de.yml new file mode 100644 index 000000000..4fffdd85a --- /dev/null +++ b/config/locales/de.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/el.yml b/config/locales/el.yml new file mode 100644 index 000000000..ba00cae28 --- /dev/null +++ b/config/locales/el.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml new file mode 100644 index 000000000..ceaba1ed5 --- /dev/null +++ b/config/locales/en-GB.yml @@ -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.
    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.
    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 --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..135d078d3 --- /dev/null +++ b/config/locales/en.yml @@ -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.
    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.
    Once saved, the identifier cannot be changed.' diff --git a/config/locales/es.yml b/config/locales/es.yml new file mode 100644 index 000000000..2ec4fef2a --- /dev/null +++ b/config/locales/es.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/et.yml b/config/locales/et.yml new file mode 100644 index 000000000..0764b47c4 --- /dev/null +++ b/config/locales/et.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/eu.yml b/config/locales/eu.yml new file mode 100644 index 000000000..e0aa83153 --- /dev/null +++ b/config/locales/eu.yml @@ -0,0 +1,1090 @@ +# Redmine EU language +# Author: Ales Zabala Alava (Shagi), +# 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: "1 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/fa.yml b/config/locales/fa.yml new file mode 100644 index 000000000..d31c1f707 --- /dev/null +++ b/config/locales/fa.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/fi.yml b/config/locales/fi.yml new file mode 100644 index 000000000..97564e793 --- /dev/null +++ b/config/locales/fi.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/fr.yml b/config/locales/fr.yml new file mode 100644 index 000000000..dcd8cf154 --- /dev/null +++ b/config/locales/fr.yml @@ -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.
    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.
    Un fois sauvegardé, l''identifiant ne pourra plus être modifié.' diff --git a/config/locales/gl.yml b/config/locales/gl.yml new file mode 100644 index 000000000..ca14126f8 --- /dev/null +++ b/config/locales/gl.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/he.yml b/config/locales/he.yml new file mode 100644 index 000000000..c7ace5a9e --- /dev/null +++ b/config/locales/he.yml @@ -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 hour" + other: "%{count} hours" + 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/<instance>/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.
    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.
    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 --git a/config/locales/hr.yml b/config/locales/hr.yml new file mode 100644 index 000000000..26274f775 --- /dev/null +++ b/config/locales/hr.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/hu.yml b/config/locales/hu.yml new file mode 100644 index 000000000..4ffe7516c --- /dev/null +++ b/config/locales/hu.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/id.yml b/config/locales/id.yml new file mode 100644 index 000000000..5dc5afeb5 --- /dev/null +++ b/config/locales/id.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/it.yml b/config/locales/it.yml new file mode 100644 index 000000000..5ea2631ab --- /dev/null +++ b/config/locales/it.yml @@ -0,0 +1,1090 @@ +# 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 hour" + other: "%{count} hours" + 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: "Failed to save %{count} time entrie(s) on %{total} selected: %{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_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.
    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.
    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: tutti + label_last_n_weeks: last %{count} weeks + setting_cross_project_subtasks: Allow cross-project subtasks + 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 + 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: Totale diff --git a/config/locales/ja.yml b/config/locales/ja.yml new file mode 100644 index 000000000..bbf975459 --- /dev/null +++ b/config/locales/ja.yml @@ -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)・数字・ãƒã‚¤ãƒ•ン・アンダースコアãŒä½¿ãˆã¾ã™ã€‚最åˆã®æ–‡å­—ã¯ã‚¢ãƒ«ãƒ•ァベットã®å°æ–‡å­—ã«ã—ã¦ãã ã•ã„。
    識別å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + 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)・数字・ãƒã‚¤ãƒ•ン・アンダースコアãŒä½¿ãˆã¾ã™ã€‚
    識別å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 + 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 --git a/config/locales/ko.yml b/config/locales/ko.yml new file mode 100644 index 000000000..eeec637e4 --- /dev/null +++ b/config/locales/ko.yml @@ -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 hour" + other: "%{count} hours" + 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),숫ìž,대쉬(-)와 밑줄(_)ë§Œ 가능합니다.
    ì‹ë³„ìžëŠ” 저장후ì—는 수정할 수 없습니다." + 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),숫ìž,대쉬(-)와 밑줄(_)ë§Œ 가능합니다.
    ì‹ë³„ìžëŠ” 저장후ì—는 수정할 수 없습니다." + 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 --git a/config/locales/lt.yml b/config/locales/lt.yml new file mode 100644 index 000000000..1b24ccf91 --- /dev/null +++ b/config/locales/lt.yml @@ -0,0 +1,1149 @@ +# 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į" + error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})" + 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.
    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.
    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.
    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 --git a/config/locales/lv.yml b/config/locales/lv.yml new file mode 100644 index 000000000..9c3de7416 --- /dev/null +++ b/config/locales/lv.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/mk.yml b/config/locales/mk.yml new file mode 100644 index 000000000..61b219c31 --- /dev/null +++ b/config/locales/mk.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/mn.yml b/config/locales/mn.yml new file mode 100644 index 000000000..359869373 --- /dev/null +++ b/config/locales/mn.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/nl.yml b/config/locales/nl.yml new file mode 100644 index 000000000..6afc2373c --- /dev/null +++ b/config/locales/nl.yml @@ -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} hours" + 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.
    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.
    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 --git a/config/locales/no.yml b/config/locales/no.yml new file mode 100644 index 000000000..e2249c594 --- /dev/null +++ b/config/locales/no.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/pl.yml b/config/locales/pl.yml new file mode 100644 index 000000000..c9ff4dd58 --- /dev/null +++ b/config/locales/pl.yml @@ -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 hour" + other: "%{count} hours" + 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 , 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.
    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.
    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 --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml new file mode 100644 index 000000000..0752e847c --- /dev/null +++ b/config/locales/pt-BR.yml @@ -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.
    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
    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: Default trackers for new projects + label_total_time: Total diff --git a/config/locales/pt.yml b/config/locales/pt.yml new file mode 100644 index 000000000..5deff0a68 --- /dev/null +++ b/config/locales/pt.yml @@ -0,0 +1,1095 @@ +# Portuguese localization for Ruby on Rails +# by Ricardo Otero +# by Alberto Ferreira +# by Rui Rebelo +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 + 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.
    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.
    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 --git a/config/locales/ro.yml b/config/locales/ro.yml new file mode 100644 index 000000000..6f72e7b8b --- /dev/null +++ b/config/locales/ro.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/ru.yml b/config/locales/ru.yml new file mode 100644 index 000000000..634b57771 --- /dev/null +++ b/config/locales/ru.yml @@ -0,0 +1,1199 @@ +# Russian localization for Ruby on Rails 2.2+ +# by Yaroslav Markin +# +# 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: Параметр «Ð³Ð¾Ñ‚овноÑть» обновлён. + 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), цифры, тире и подчеркиваниÑ.
    ПоÑле ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ изменить нельзÑ. + 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), цифры, тире и подчеркиваниÑ.
    ПоÑле ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ изменить нельзÑ. + 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 --git a/config/locales/sk.yml b/config/locales/sk.yml new file mode 100644 index 000000000..f8924c894 --- /dev/null +++ b/config/locales/sk.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/sl.yml b/config/locales/sl.yml new file mode 100644 index 000000000..8c6e22b40 --- /dev/null +++ b/config/locales/sl.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/sq.yml b/config/locales/sq.yml new file mode 100644 index 000000000..05e5a6f79 --- /dev/null +++ b/config/locales/sq.yml @@ -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 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: "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.
    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.
    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 --git a/config/locales/sr-YU.yml b/config/locales/sr-YU.yml new file mode 100644 index 000000000..3b53e6ee5 --- /dev/null +++ b/config/locales/sr-YU.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/sr.yml b/config/locales/sr.yml new file mode 100644 index 000000000..f5573c96c --- /dev/null +++ b/config/locales/sr.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/sv.yml b/config/locales/sv.yml new file mode 100644 index 000000000..b44b566b0 --- /dev/null +++ b/config/locales/sv.yml @@ -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_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 + + 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 + + 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_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.
    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.
    När identifieraren sparats kan den inte ändras.' + 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 --git a/config/locales/th.yml b/config/locales/th.yml new file mode 100644 index 000000000..a7e1255ea --- /dev/null +++ b/config/locales/th.yml @@ -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.
    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.
    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 --git a/config/locales/tr.yml b/config/locales/tr.yml new file mode 100644 index 000000000..757af1a91 --- /dev/null +++ b/config/locales/tr.yml @@ -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 hour" + other: "%{count} hours" + 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.
    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.
    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 --git a/config/locales/uk.yml b/config/locales/uk.yml new file mode 100644 index 000000000..ddfd3ffa3 --- /dev/null +++ b/config/locales/uk.yml @@ -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.
    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.
    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 --git a/config/locales/vi.yml b/config/locales/vi.yml new file mode 100644 index 000000000..8703db8e6 --- /dev/null +++ b/config/locales/vi.yml @@ -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 » + 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.
    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ệ.
    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 --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml new file mode 100644 index 000000000..196b0ce98 --- /dev/null +++ b/config/locales/zh-TW.yml @@ -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 hour" + other: "%{count} hours" + 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), 阿拉伯數字, 虛線與底線。
    一旦儲存之後, ä»£ç¢¼ä¾¿ç„¡æ³•å†æ¬¡è¢«æ›´æ”¹ã€‚' + 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), 阿拉伯數字, 虛線與底線。
    一旦儲存之後, ä»£ç¢¼ä¾¿ç„¡æ³•å†æ¬¡è¢«æ›´æ”¹ã€‚' + label_total_time: 總計 diff --git a/config/locales/zh.yml b/config/locales/zh.yml new file mode 100644 index 000000000..846b9b65e --- /dev/null +++ b/config/locales/zh.yml @@ -0,0 +1,1149 @@ + +# 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: 主页 + #by young + label_requirement: 需求 + label_requirement_focus: 关注需求 + label_developer: å¼€å‘者 + label_investor: 投资人 + label_theme: 主题 + label_logged_as_new: 当å‰ç”¨æˆ· + button_register: 注册 + issue_list: 缺陷列表 + lastest_respond: 最新å馈 + label_respond_view_all: å…¶ä»–120个å馈 + label_news_lastest: æœ€æ–°åŠ¨æ€ + #end + 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: "æ”¶å–æˆ‘的项目的所有通知" + #huang + label_user_edit: "修改资料" + label_user_info: "个人简介" #huang 添加 + label_user_watcher: "关注" # huang添加的 + label_user_commits: "ä»£ç æäº¤" + label_user_watchered: "被关注" # huang添加的 + label_user_newfeedback: "留言" ## huang添加的 + #。。 + 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ï¼‰ã€æ•°å­—ã€ç ´æŠ˜å·ï¼ˆ-)和下划线(_)å¯ä»¥ä½¿ç”¨ã€‚
    一旦ä¿å­˜ï¼Œæ ‡è¯†æ— æ³•修改。 + 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ï¼‰ã€æ•°å­—ã€ç ´æŠ˜å·ï¼ˆ-)和下划线(_)å¯ä»¥ä½¿ç”¨ã€‚
    一旦ä¿å­˜ï¼Œæ ‡è¯†æ— æ³•修改。 + 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: åˆè®¡ + + label_create_time: 创建时间 #Customer addedï¼ + label_current_contributors: ä½å½“å‰è´¡çŒ®è€… + label_lines_of_code: è¡Œä»£ç  + label_since_last_commits: è·ç¦»ä¸Šæ¬¡æäº¤æ—¶é—´ + label_users_on_trustie: 用户 + label_front: 第一页 + label_commit_on: 次æäº¤ + label_follow_people: 个关注者 + label_member_since: 加入trustie2 + label_contribute_to: å‚与了%{project_count}个项目: + label_total_commit: å…±%{total_commit}次æäº¤ + label_upload_profile: ä¸Šä¼ å¤´åƒ + label_type_as: 类型为 + label_status_as: 状æ€ä¸º + label_priority_as: 优先级为 + label_member_list: æˆå‘˜åˆ—表 + + #added by liuping + button_unfollow: å–æ¶ˆå…³æ³¨ + button_follow: 关注 + label_delete_confirm: 确认删除? + label_more_tags: 更多 + #fq + button_leave_meassge: 留言 + label_leave_message_to: 给用户 %{name}留言 + label_leave_message: 留言内容 + label_message: ç•™è¨€æ¿ + field_add: 添加于 %{time} ä¹‹å‰ + button_more: 更多 + label_user_response: 用户å馈 + label_bidding_project: 应标项目 + button_bidding: 我è¦åº”æ ‡ + diff --git a/config/preinitializer.rb b/config/preinitializer.rb new file mode 100644 index 000000000..90f789c6d --- /dev/null +++ b/config/preinitializer.rb @@ -0,0 +1,20 @@ +begin + require "rubygems" + require "bundler" +rescue LoadError + $stderr.puts "Redmine requires Bundler. Please install it with `gem install bundler`." + exit 1 +end + +if Gem::Version.new(Bundler::VERSION) < Gem::Version.new("1.0.21") + $stderr.puts "Redmine requires Bundler 1.0.21 (you're using #{Bundler::VERSION}).\nPlease install a newer version with `gem install bundler`." + exit 1 +end + +begin + ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) + Bundler.setup +rescue Bundler::GemNotFound + $stderr.puts "Some gems may need to be installed or updated.\nPlease run `bundle install --without development test`." + exit 1 +end diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..51daeb281 --- /dev/null +++ b/config/routes.rb @@ -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. + +RedmineApp::Application.routes.draw do + get "tags/index" + + get "tags/show" + + 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' + + #added by young + resources :users do + member do + match 'user_projects', :to => 'users#user_projects', :via => :get, :as => "user_projects" + match 'user_activities', :to => 'users#show', :via => :get, :as => "user_activities" + match 'user_newfeedback', :to => 'users#user_newfeedback', :via => :get, :as => "user_newfeedback" + end + end +#end + 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' + ################# added by william + match 'users/tag_save', :to => 'users#tag_save', :via => :post, :as => 'tag' + + 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' + get 'show', :action => 'show', :as => 'project_show' + get 'activity', :controller => 'activities', :action => 'index', :as => 'activity' + get 'repository', :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil, :as => 'repository' + #by young + get 'member', :controller => 'projects', :action => 'member', :as => 'member' + get 'focus', :action => 'focus', :as => 'focus' + get 'investor', :action => 'investor', :as => 'investor' +# get 'issue', :action =>'issue', :as => 'issue' + get 'mission', :action => 'mission', :as => 'mission' + get 'on', :action => 'on', :as => 'on' + get 'file', :action => 'file', :as => 'file' + #end + + post 'modules' + post 'archive' + post 'unarchive' + post 'close' + post 'reopen' + match 'copy', :via => [:get, :post] + end + +#by young + match '/member', :controller => 'projects', :action => 'member', :as => 'member', :via => :get + match '/focus', :controller => 'projects', :action => 'focus', :as => 'focus', :via => :get + match '/mission', :controller => 'projects', :action => 'mission', :as => 'mission', :via => :get + match '/on', :controller => 'projects', :action => 'on', :as => 'on', :via => :get + match '/settings(/:tab)', :controller => 'projects', :action => 'settings', :as => 'settings', :via => :get + match '/file', :controller => 'projects', :action => 'file', :as => 'file', :via => :get + match '/investor', :controller => 'projects', :action => 'investor', :as => 'investor', :via => :get + + match '/activity', :controller => 'activities', :action => 'index', :as => 'activity', :via => :get + match '/repository', :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil, :as => 'repository', :via => :get + match '/', :controller => 'projects', :action => 'show', :as => 'project_show', :via => :get + get 'projects/:project_id/show', :to => 'projects#show', :as => 'project_show' + get 'projects/:project_id/repository', :to => 'repositories#show', :as => 'project_repository' + +# match '/show', :controller => 'projects', :action => 'show', :as => 'project_show', :via => :get + +#end + + resources :memberships, :shallow => true, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do + collection do + get 'autocomplete' + 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] + resources :issue_categories, :shallow => true + resources :documents, :except => [:show, :edit, :update, :destroy] + resources :boards + resources :repositories, :shallow => true, :except => [:index, :show] do + member do + match 'committers', :via => [:get, :post] + 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 + resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy] + 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 + # Added by Tao + match 'upload_avatar', :to => 'avatar#upload', :via => :post + # Endof Tao's code + 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 + + ##############测试留言功能 fq + post 'words/new', :to => 'words#new' + post 'words/create', :to => 'words#create' + post 'words/append', :to => 'words#append' + delete 'words/destroy', :to => 'words#destroy' + get 'words/more', :to => 'words#more' + get 'words/back', :to=> 'words#back' + ############## + post 'bids/create', :to => 'bids#create' + delete 'bids/destroy', :to => 'bids#destroy' + get 'bids/more', :to => 'bids#more' + get 'bids/back', :to=> 'bids#back' + match 'bids/:bid_id/show_project', :controller => 'bids', :action => 'show_project' + match 'bids/:bid_id/add', :controller => 'bids', :action => 'add' + match 'bids/new_bid', :controller => 'bids', :action => 'new_bid' + # added by young + match 'bids', :controller => 'bids', :action => 'index' + + match 'bids/:bid_id/show', :controller => 'bids', :action => 'show' + match 'bids/new', :controller => 'bids', :action => 'new', :via => [:get , :post] + + + ########### added by liuping + match 'tags/add_tag',:to => 'tags#add_tag',:as=>"add_tag" + match 'tags/delete_tag',:to => 'tags#delete_tag',:as=>"add_tag" + +end diff --git a/config/settings.yml b/config/settings.yml new file mode 100644 index 000000000..384e7d07b --- /dev/null +++ b/config/settings.yml @@ -0,0 +1,238 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public 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' + + +#### added by liuping +show_tags_length: + format: int + default: 5 diff --git a/db/development.sqlite3 b/db/development.sqlite3 new file mode 100644 index 000000000..e69de29bb diff --git a/db/migrate/001_setup.rb b/db/migrate/001_setup.rb new file mode 100644 index 000000000..f1b9c1ed4 --- /dev/null +++ b/db/migrate/001_setup.rb @@ -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 --git a/db/migrate/002_issue_move.rb b/db/migrate/002_issue_move.rb new file mode 100644 index 000000000..98e95d3b9 --- /dev/null +++ b/db/migrate/002_issue_move.rb @@ -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 --git a/db/migrate/003_issue_add_note.rb b/db/migrate/003_issue_add_note.rb new file mode 100644 index 000000000..dabdb858f --- /dev/null +++ b/db/migrate/003_issue_add_note.rb @@ -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 --git a/db/migrate/004_export_pdf.rb b/db/migrate/004_export_pdf.rb new file mode 100644 index 000000000..8d4ba0b3a --- /dev/null +++ b/db/migrate/004_export_pdf.rb @@ -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 --git a/db/migrate/005_issue_start_date.rb b/db/migrate/005_issue_start_date.rb new file mode 100644 index 000000000..3d1693fc6 --- /dev/null +++ b/db/migrate/005_issue_start_date.rb @@ -0,0 +1,11 @@ +class IssueStartDate < ActiveRecord::Migration + def self.up + add_column :issues, :start_date, :date + add_column :issues, :done_ratio, :integer, :default => 0, :null => false + end + + def self.down + remove_column :issues, :start_date + remove_column :issues, :done_ratio + end +end diff --git a/db/migrate/006_calendar_and_activity.rb b/db/migrate/006_calendar_and_activity.rb new file mode 100644 index 000000000..a30979a21 --- /dev/null +++ b/db/migrate/006_calendar_and_activity.rb @@ -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 --git a/db/migrate/007_create_journals.rb b/db/migrate/007_create_journals.rb new file mode 100644 index 000000000..63bdd2374 --- /dev/null +++ b/db/migrate/007_create_journals.rb @@ -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 --git a/db/migrate/008_create_user_preferences.rb b/db/migrate/008_create_user_preferences.rb new file mode 100644 index 000000000..80ae1cdf9 --- /dev/null +++ b/db/migrate/008_create_user_preferences.rb @@ -0,0 +1,12 @@ +class CreateUserPreferences < ActiveRecord::Migration + def self.up + create_table :user_preferences do |t| + t.column "user_id", :integer, :default => 0, :null => false + t.column "others", :text + end + end + + def self.down + drop_table :user_preferences + end +end diff --git a/db/migrate/009_add_hide_mail_pref.rb b/db/migrate/009_add_hide_mail_pref.rb new file mode 100644 index 000000000..a22eafd93 --- /dev/null +++ b/db/migrate/009_add_hide_mail_pref.rb @@ -0,0 +1,9 @@ +class AddHideMailPref < ActiveRecord::Migration + def self.up + add_column :user_preferences, :hide_mail, :boolean, :default => false + end + + def self.down + remove_column :user_preferences, :hide_mail + end +end diff --git a/db/migrate/010_create_comments.rb b/db/migrate/010_create_comments.rb new file mode 100644 index 000000000..29e1116af --- /dev/null +++ b/db/migrate/010_create_comments.rb @@ -0,0 +1,16 @@ +class CreateComments < ActiveRecord::Migration + def self.up + create_table :comments do |t| + t.column :commented_type, :string, :limit => 30, :default => "", :null => false + t.column :commented_id, :integer, :default => 0, :null => false + t.column :author_id, :integer, :default => 0, :null => false + t.column :comments, :text + t.column :created_on, :datetime, :null => false + t.column :updated_on, :datetime, :null => false + end + end + + def self.down + drop_table :comments + end +end diff --git a/db/migrate/011_add_news_comments_count.rb b/db/migrate/011_add_news_comments_count.rb new file mode 100644 index 000000000..a24743999 --- /dev/null +++ b/db/migrate/011_add_news_comments_count.rb @@ -0,0 +1,9 @@ +class AddNewsCommentsCount < ActiveRecord::Migration + def self.up + add_column :news, :comments_count, :integer, :default => 0, :null => false + end + + def self.down + remove_column :news, :comments_count + end +end diff --git a/db/migrate/012_add_comments_permissions.rb b/db/migrate/012_add_comments_permissions.rb new file mode 100644 index 000000000..91eed6443 --- /dev/null +++ b/db/migrate/012_add_comments_permissions.rb @@ -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 --git a/db/migrate/013_create_queries.rb b/db/migrate/013_create_queries.rb new file mode 100644 index 000000000..e0e8c90c0 --- /dev/null +++ b/db/migrate/013_create_queries.rb @@ -0,0 +1,15 @@ +class CreateQueries < ActiveRecord::Migration + def self.up + create_table :queries, :force => true do |t| + t.column "project_id", :integer + t.column "name", :string, :default => "", :null => false + t.column "filters", :text + t.column "user_id", :integer, :default => 0, :null => false + t.column "is_public", :boolean, :default => false, :null => false + end + end + + def self.down + drop_table :queries + end +end diff --git a/db/migrate/014_add_queries_permissions.rb b/db/migrate/014_add_queries_permissions.rb new file mode 100644 index 000000000..ae1f2455d --- /dev/null +++ b/db/migrate/014_add_queries_permissions.rb @@ -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 --git a/db/migrate/015_create_repositories.rb b/db/migrate/015_create_repositories.rb new file mode 100644 index 000000000..d8c0524b3 --- /dev/null +++ b/db/migrate/015_create_repositories.rb @@ -0,0 +1,12 @@ +class CreateRepositories < ActiveRecord::Migration + def self.up + create_table :repositories, :force => true do |t| + t.column "project_id", :integer, :default => 0, :null => false + t.column "url", :string, :default => "", :null => false + end + end + + def self.down + drop_table :repositories + end +end diff --git a/db/migrate/016_add_repositories_permissions.rb b/db/migrate/016_add_repositories_permissions.rb new file mode 100644 index 000000000..9fcddb09c --- /dev/null +++ b/db/migrate/016_add_repositories_permissions.rb @@ -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 --git a/db/migrate/017_create_settings.rb b/db/migrate/017_create_settings.rb new file mode 100644 index 000000000..99f96adf8 --- /dev/null +++ b/db/migrate/017_create_settings.rb @@ -0,0 +1,12 @@ +class CreateSettings < ActiveRecord::Migration + def self.up + create_table :settings, :force => true do |t| + t.column "name", :string, :limit => 30, :default => "", :null => false + t.column "value", :text + end + end + + def self.down + drop_table :settings + end +end diff --git a/db/migrate/018_set_doc_and_files_notifications.rb b/db/migrate/018_set_doc_and_files_notifications.rb new file mode 100644 index 000000000..8c1d054c1 --- /dev/null +++ b/db/migrate/018_set_doc_and_files_notifications.rb @@ -0,0 +1,18 @@ +class SetDocAndFilesNotifications < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.find_by_controller_and_action("projects", "add_file").update_attribute(:mail_option, true) + Permission.find_by_controller_and_action("projects", "add_document").update_attribute(:mail_option, true) + Permission.find_by_controller_and_action("documents", "add_attachment").update_attribute(:mail_option, true) + Permission.find_by_controller_and_action("issues", "add_attachment").update_attribute(:mail_option, true) + end + + def self.down + Permission.find_by_controller_and_action("projects", "add_file").update_attribute(:mail_option, false) + Permission.find_by_controller_and_action("projects", "add_document").update_attribute(:mail_option, false) + Permission.find_by_controller_and_action("documents", "add_attachment").update_attribute(:mail_option, false) + Permission.find_by_controller_and_action("issues", "add_attachment").update_attribute(:mail_option, false) + end +end diff --git a/db/migrate/019_add_issue_status_position.rb b/db/migrate/019_add_issue_status_position.rb new file mode 100644 index 000000000..012f97c22 --- /dev/null +++ b/db/migrate/019_add_issue_status_position.rb @@ -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 --git a/db/migrate/020_add_role_position.rb b/db/migrate/020_add_role_position.rb new file mode 100644 index 000000000..48ac89a36 --- /dev/null +++ b/db/migrate/020_add_role_position.rb @@ -0,0 +1,10 @@ +class AddRolePosition < ActiveRecord::Migration + def self.up + add_column :roles, :position, :integer, :default => 1 + Role.all.each_with_index {|role, i| role.update_attribute(:position, i+1)} + end + + def self.down + remove_column :roles, :position + end +end diff --git a/db/migrate/021_add_tracker_position.rb b/db/migrate/021_add_tracker_position.rb new file mode 100644 index 000000000..5fa8a3185 --- /dev/null +++ b/db/migrate/021_add_tracker_position.rb @@ -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 --git a/db/migrate/022_serialize_possibles_values.rb b/db/migrate/022_serialize_possibles_values.rb new file mode 100644 index 000000000..3e9fed0a1 --- /dev/null +++ b/db/migrate/022_serialize_possibles_values.rb @@ -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 --git a/db/migrate/023_add_tracker_is_in_roadmap.rb b/db/migrate/023_add_tracker_is_in_roadmap.rb new file mode 100644 index 000000000..82ef87bba --- /dev/null +++ b/db/migrate/023_add_tracker_is_in_roadmap.rb @@ -0,0 +1,9 @@ +class AddTrackerIsInRoadmap < ActiveRecord::Migration + def self.up + add_column :trackers, :is_in_roadmap, :boolean, :default => true, :null => false + end + + def self.down + remove_column :trackers, :is_in_roadmap + end +end diff --git a/db/migrate/024_add_roadmap_permission.rb b/db/migrate/024_add_roadmap_permission.rb new file mode 100644 index 000000000..f521e6025 --- /dev/null +++ b/db/migrate/024_add_roadmap_permission.rb @@ -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 --git a/db/migrate/025_add_search_permission.rb b/db/migrate/025_add_search_permission.rb new file mode 100644 index 000000000..a942b01b3 --- /dev/null +++ b/db/migrate/025_add_search_permission.rb @@ -0,0 +1,12 @@ +class AddSearchPermission < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => "projects", :action => "search", :description => "label_search", :sort => 130, :is_public => true, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('projects', 'search').destroy + end +end diff --git a/db/migrate/026_add_repository_login_and_password.rb b/db/migrate/026_add_repository_login_and_password.rb new file mode 100644 index 000000000..5fc919725 --- /dev/null +++ b/db/migrate/026_add_repository_login_and_password.rb @@ -0,0 +1,11 @@ +class AddRepositoryLoginAndPassword < ActiveRecord::Migration + def self.up + add_column :repositories, :login, :string, :limit => 60, :default => "" + add_column :repositories, :password, :string, :limit => 60, :default => "" + end + + def self.down + remove_column :repositories, :login + remove_column :repositories, :password + end +end diff --git a/db/migrate/027_create_wikis.rb b/db/migrate/027_create_wikis.rb new file mode 100644 index 000000000..284eee2e2 --- /dev/null +++ b/db/migrate/027_create_wikis.rb @@ -0,0 +1,14 @@ +class CreateWikis < ActiveRecord::Migration + def self.up + create_table :wikis do |t| + t.column :project_id, :integer, :null => false + t.column :start_page, :string, :limit => 255, :null => false + t.column :status, :integer, :default => 1, :null => false + end + add_index :wikis, :project_id, :name => :wikis_project_id + end + + def self.down + drop_table :wikis + end +end diff --git a/db/migrate/028_create_wiki_pages.rb b/db/migrate/028_create_wiki_pages.rb new file mode 100644 index 000000000..e2282125a --- /dev/null +++ b/db/migrate/028_create_wiki_pages.rb @@ -0,0 +1,14 @@ +class CreateWikiPages < ActiveRecord::Migration + def self.up + create_table :wiki_pages do |t| + t.column :wiki_id, :integer, :null => false + t.column :title, :string, :limit => 255, :null => false + t.column :created_on, :datetime, :null => false + end + add_index :wiki_pages, [:wiki_id, :title], :name => :wiki_pages_wiki_id_title + end + + def self.down + drop_table :wiki_pages + end +end diff --git a/db/migrate/029_create_wiki_contents.rb b/db/migrate/029_create_wiki_contents.rb new file mode 100644 index 000000000..5b6a22f94 --- /dev/null +++ b/db/migrate/029_create_wiki_contents.rb @@ -0,0 +1,30 @@ +class CreateWikiContents < ActiveRecord::Migration + def self.up + create_table :wiki_contents do |t| + t.column :page_id, :integer, :null => false + t.column :author_id, :integer + t.column :text, :text + t.column :comments, :string, :limit => 255, :default => "" + t.column :updated_on, :datetime, :null => false + t.column :version, :integer, :null => false + end + add_index :wiki_contents, :page_id, :name => :wiki_contents_page_id + + create_table :wiki_content_versions do |t| + t.column :wiki_content_id, :integer, :null => false + t.column :page_id, :integer, :null => false + t.column :author_id, :integer + t.column :data, :binary + t.column :compression, :string, :limit => 6, :default => "" + t.column :comments, :string, :limit => 255, :default => "" + t.column :updated_on, :datetime, :null => false + t.column :version, :integer, :null => false + end + add_index :wiki_content_versions, :wiki_content_id, :name => :wiki_content_versions_wcid + end + + def self.down + drop_table :wiki_contents + drop_table :wiki_content_versions + end +end diff --git a/db/migrate/030_add_projects_feeds_permissions.rb b/db/migrate/030_add_projects_feeds_permissions.rb new file mode 100644 index 000000000..7f97035bf --- /dev/null +++ b/db/migrate/030_add_projects_feeds_permissions.rb @@ -0,0 +1,12 @@ +class AddProjectsFeedsPermissions < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => "projects", :action => "feeds", :description => "label_feed_plural", :sort => 132, :is_public => true, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('projects', 'feeds').destroy + end +end diff --git a/db/migrate/031_add_repository_root_url.rb b/db/migrate/031_add_repository_root_url.rb new file mode 100644 index 000000000..df57809c7 --- /dev/null +++ b/db/migrate/031_add_repository_root_url.rb @@ -0,0 +1,9 @@ +class AddRepositoryRootUrl < ActiveRecord::Migration + def self.up + add_column :repositories, :root_url, :string, :limit => 255, :default => "" + end + + def self.down + remove_column :repositories, :root_url + end +end diff --git a/db/migrate/032_create_time_entries.rb b/db/migrate/032_create_time_entries.rb new file mode 100644 index 000000000..9b9a54eb1 --- /dev/null +++ b/db/migrate/032_create_time_entries.rb @@ -0,0 +1,24 @@ +class CreateTimeEntries < ActiveRecord::Migration + def self.up + create_table :time_entries do |t| + t.column :project_id, :integer, :null => false + t.column :user_id, :integer, :null => false + t.column :issue_id, :integer + t.column :hours, :float, :null => false + t.column :comments, :string, :limit => 255 + t.column :activity_id, :integer, :null => false + t.column :spent_on, :date, :null => false + t.column :tyear, :integer, :null => false + t.column :tmonth, :integer, :null => false + t.column :tweek, :integer, :null => false + t.column :created_on, :datetime, :null => false + t.column :updated_on, :datetime, :null => false + end + add_index :time_entries, [:project_id], :name => :time_entries_project_id + add_index :time_entries, [:issue_id], :name => :time_entries_issue_id + end + + def self.down + drop_table :time_entries + end +end diff --git a/db/migrate/033_add_timelog_permissions.rb b/db/migrate/033_add_timelog_permissions.rb new file mode 100644 index 000000000..ab9c809e6 --- /dev/null +++ b/db/migrate/033_add_timelog_permissions.rb @@ -0,0 +1,12 @@ +class AddTimelogPermissions < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => "timelog", :action => "edit", :description => "button_log_time", :sort => 1520, :is_public => false, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('timelog', 'edit').destroy + end +end diff --git a/db/migrate/034_create_changesets.rb b/db/migrate/034_create_changesets.rb new file mode 100644 index 000000000..612fd46bb --- /dev/null +++ b/db/migrate/034_create_changesets.rb @@ -0,0 +1,16 @@ +class CreateChangesets < ActiveRecord::Migration + def self.up + create_table :changesets do |t| + t.column :repository_id, :integer, :null => false + t.column :revision, :integer, :null => false + t.column :committer, :string, :limit => 30 + t.column :committed_on, :datetime, :null => false + t.column :comments, :text + end + add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev + end + + def self.down + drop_table :changesets + end +end diff --git a/db/migrate/035_create_changes.rb b/db/migrate/035_create_changes.rb new file mode 100644 index 000000000..fa0cfac3f --- /dev/null +++ b/db/migrate/035_create_changes.rb @@ -0,0 +1,16 @@ +class CreateChanges < ActiveRecord::Migration + def self.up + create_table :changes do |t| + t.column :changeset_id, :integer, :null => false + t.column :action, :string, :limit => 1, :default => "", :null => false + t.column :path, :string, :default => "", :null => false + t.column :from_path, :string + t.column :from_revision, :integer + end + add_index :changes, [:changeset_id], :name => :changesets_changeset_id + end + + def self.down + drop_table :changes + end +end diff --git a/db/migrate/036_add_changeset_commit_date.rb b/db/migrate/036_add_changeset_commit_date.rb new file mode 100644 index 000000000..b9cc49b84 --- /dev/null +++ b/db/migrate/036_add_changeset_commit_date.rb @@ -0,0 +1,10 @@ +class AddChangesetCommitDate < ActiveRecord::Migration + def self.up + add_column :changesets, :commit_date, :date + Changeset.update_all "commit_date = committed_on" + end + + def self.down + remove_column :changesets, :commit_date + end +end diff --git a/db/migrate/037_add_project_identifier.rb b/db/migrate/037_add_project_identifier.rb new file mode 100644 index 000000000..0fd8c7513 --- /dev/null +++ b/db/migrate/037_add_project_identifier.rb @@ -0,0 +1,9 @@ +class AddProjectIdentifier < ActiveRecord::Migration + def self.up + add_column :projects, :identifier, :string, :limit => 20 + end + + def self.down + remove_column :projects, :identifier + end +end diff --git a/db/migrate/038_add_custom_field_is_filter.rb b/db/migrate/038_add_custom_field_is_filter.rb new file mode 100644 index 000000000..519ee0bd5 --- /dev/null +++ b/db/migrate/038_add_custom_field_is_filter.rb @@ -0,0 +1,9 @@ +class AddCustomFieldIsFilter < ActiveRecord::Migration + def self.up + add_column :custom_fields, :is_filter, :boolean, :null => false, :default => false + end + + def self.down + remove_column :custom_fields, :is_filter + end +end diff --git a/db/migrate/039_create_watchers.rb b/db/migrate/039_create_watchers.rb new file mode 100644 index 000000000..9579e19a4 --- /dev/null +++ b/db/migrate/039_create_watchers.rb @@ -0,0 +1,13 @@ +class CreateWatchers < ActiveRecord::Migration + def self.up + create_table :watchers do |t| + t.column :watchable_type, :string, :default => "", :null => false + t.column :watchable_id, :integer, :default => 0, :null => false + t.column :user_id, :integer + end + end + + def self.down + drop_table :watchers + end +end diff --git a/db/migrate/040_create_changesets_issues.rb b/db/migrate/040_create_changesets_issues.rb new file mode 100644 index 000000000..494d3cc46 --- /dev/null +++ b/db/migrate/040_create_changesets_issues.rb @@ -0,0 +1,13 @@ +class CreateChangesetsIssues < ActiveRecord::Migration + def self.up + create_table :changesets_issues, :id => false do |t| + t.column :changeset_id, :integer, :null => false + t.column :issue_id, :integer, :null => false + end + add_index :changesets_issues, [:changeset_id, :issue_id], :unique => true, :name => :changesets_issues_ids + end + + def self.down + drop_table :changesets_issues + end +end diff --git a/db/migrate/041_rename_comment_to_comments.rb b/db/migrate/041_rename_comment_to_comments.rb new file mode 100644 index 000000000..93677e575 --- /dev/null +++ b/db/migrate/041_rename_comment_to_comments.rb @@ -0,0 +1,13 @@ +class RenameCommentToComments < ActiveRecord::Migration + def self.up + rename_column(:comments, :comment, :comments) if ActiveRecord::Base.connection.columns(Comment.table_name).detect{|c| c.name == "comment"} + rename_column(:wiki_contents, :comment, :comments) if ActiveRecord::Base.connection.columns(WikiContent.table_name).detect{|c| c.name == "comment"} + rename_column(:wiki_content_versions, :comment, :comments) if ActiveRecord::Base.connection.columns(WikiContent.versioned_table_name).detect{|c| c.name == "comment"} + rename_column(:time_entries, :comment, :comments) if ActiveRecord::Base.connection.columns(TimeEntry.table_name).detect{|c| c.name == "comment"} + rename_column(:changesets, :comment, :comments) if ActiveRecord::Base.connection.columns(Changeset.table_name).detect{|c| c.name == "comment"} + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/042_create_issue_relations.rb b/db/migrate/042_create_issue_relations.rb new file mode 100644 index 000000000..802c12437 --- /dev/null +++ b/db/migrate/042_create_issue_relations.rb @@ -0,0 +1,14 @@ +class CreateIssueRelations < ActiveRecord::Migration + def self.up + create_table :issue_relations do |t| + t.column :issue_from_id, :integer, :null => false + t.column :issue_to_id, :integer, :null => false + t.column :relation_type, :string, :default => "", :null => false + t.column :delay, :integer + end + end + + def self.down + drop_table :issue_relations + end +end diff --git a/db/migrate/043_add_relations_permissions.rb b/db/migrate/043_add_relations_permissions.rb new file mode 100644 index 000000000..32d464a58 --- /dev/null +++ b/db/migrate/043_add_relations_permissions.rb @@ -0,0 +1,14 @@ +class AddRelationsPermissions < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => "issue_relations", :action => "new", :description => "label_relation_new", :sort => 1080, :is_public => false, :mail_option => 0, :mail_enabled => 0 + Permission.create :controller => "issue_relations", :action => "destroy", :description => "label_relation_delete", :sort => 1085, :is_public => false, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action("issue_relations", "new").destroy + Permission.find_by_controller_and_action("issue_relations", "destroy").destroy + end +end diff --git a/db/migrate/044_set_language_length_to_five.rb b/db/migrate/044_set_language_length_to_five.rb new file mode 100644 index 000000000..a417f7d70 --- /dev/null +++ b/db/migrate/044_set_language_length_to_five.rb @@ -0,0 +1,9 @@ +class SetLanguageLengthToFive < ActiveRecord::Migration + def self.up + change_column :users, :language, :string, :limit => 5, :default => "" + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/045_create_boards.rb b/db/migrate/045_create_boards.rb new file mode 100644 index 000000000..17f2bbbe2 --- /dev/null +++ b/db/migrate/045_create_boards.rb @@ -0,0 +1,18 @@ +class CreateBoards < ActiveRecord::Migration + def self.up + create_table :boards do |t| + t.column :project_id, :integer, :null => false + t.column :name, :string, :default => "", :null => false + t.column :description, :string + t.column :position, :integer, :default => 1 + t.column :topics_count, :integer, :default => 0, :null => false + t.column :messages_count, :integer, :default => 0, :null => false + t.column :last_message_id, :integer + end + add_index :boards, [:project_id], :name => :boards_project_id + end + + def self.down + drop_table :boards + end +end diff --git a/db/migrate/046_create_messages.rb b/db/migrate/046_create_messages.rb new file mode 100644 index 000000000..d99aaf842 --- /dev/null +++ b/db/migrate/046_create_messages.rb @@ -0,0 +1,21 @@ +class CreateMessages < ActiveRecord::Migration + def self.up + create_table :messages do |t| + t.column :board_id, :integer, :null => false + t.column :parent_id, :integer + t.column :subject, :string, :default => "", :null => false + t.column :content, :text + t.column :author_id, :integer + t.column :replies_count, :integer, :default => 0, :null => false + t.column :last_reply_id, :integer + t.column :created_on, :datetime, :null => false + t.column :updated_on, :datetime, :null => false + end + add_index :messages, [:board_id], :name => :messages_board_id + add_index :messages, [:parent_id], :name => :messages_parent_id + end + + def self.down + drop_table :messages + end +end diff --git a/db/migrate/047_add_boards_permissions.rb b/db/migrate/047_add_boards_permissions.rb new file mode 100644 index 000000000..5b1f6f779 --- /dev/null +++ b/db/migrate/047_add_boards_permissions.rb @@ -0,0 +1,16 @@ +class AddBoardsPermissions < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => "boards", :action => "new", :description => "button_add", :sort => 2000, :is_public => false, :mail_option => 0, :mail_enabled => 0 + Permission.create :controller => "boards", :action => "edit", :description => "button_edit", :sort => 2005, :is_public => false, :mail_option => 0, :mail_enabled => 0 + Permission.create :controller => "boards", :action => "destroy", :description => "button_delete", :sort => 2010, :is_public => false, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action("boards", "new").destroy + Permission.find_by_controller_and_action("boards", "edit").destroy + Permission.find_by_controller_and_action("boards", "destroy").destroy + end +end diff --git a/db/migrate/048_allow_null_version_effective_date.rb b/db/migrate/048_allow_null_version_effective_date.rb new file mode 100644 index 000000000..82d2a33ec --- /dev/null +++ b/db/migrate/048_allow_null_version_effective_date.rb @@ -0,0 +1,9 @@ +class AllowNullVersionEffectiveDate < ActiveRecord::Migration + def self.up + change_column :versions, :effective_date, :date, :default => nil, :null => true + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/049_add_wiki_destroy_page_permission.rb b/db/migrate/049_add_wiki_destroy_page_permission.rb new file mode 100644 index 000000000..c82152388 --- /dev/null +++ b/db/migrate/049_add_wiki_destroy_page_permission.rb @@ -0,0 +1,12 @@ +class AddWikiDestroyPagePermission < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => 'wiki', :action => 'destroy', :description => 'button_delete', :sort => 1740, :is_public => false, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('wiki', 'destroy').destroy + end +end diff --git a/db/migrate/050_add_wiki_attachments_permissions.rb b/db/migrate/050_add_wiki_attachments_permissions.rb new file mode 100644 index 000000000..c0697be9c --- /dev/null +++ b/db/migrate/050_add_wiki_attachments_permissions.rb @@ -0,0 +1,14 @@ +class AddWikiAttachmentsPermissions < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => 'wiki', :action => 'add_attachment', :description => 'label_attachment_new', :sort => 1750, :is_public => false, :mail_option => 0, :mail_enabled => 0 + Permission.create :controller => 'wiki', :action => 'destroy_attachment', :description => 'label_attachment_delete', :sort => 1755, :is_public => false, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('wiki', 'add_attachment').destroy + Permission.find_by_controller_and_action('wiki', 'destroy_attachment').destroy + end +end diff --git a/db/migrate/051_add_project_status.rb b/db/migrate/051_add_project_status.rb new file mode 100644 index 000000000..fba36d237 --- /dev/null +++ b/db/migrate/051_add_project_status.rb @@ -0,0 +1,9 @@ +class AddProjectStatus < ActiveRecord::Migration + def self.up + add_column :projects, :status, :integer, :default => 1, :null => false + end + + def self.down + remove_column :projects, :status + end +end diff --git a/db/migrate/052_add_changes_revision.rb b/db/migrate/052_add_changes_revision.rb new file mode 100644 index 000000000..6f58c1a70 --- /dev/null +++ b/db/migrate/052_add_changes_revision.rb @@ -0,0 +1,9 @@ +class AddChangesRevision < ActiveRecord::Migration + def self.up + add_column :changes, :revision, :string + end + + def self.down + remove_column :changes, :revision + end +end diff --git a/db/migrate/053_add_changes_branch.rb b/db/migrate/053_add_changes_branch.rb new file mode 100644 index 000000000..998ce2ba5 --- /dev/null +++ b/db/migrate/053_add_changes_branch.rb @@ -0,0 +1,9 @@ +class AddChangesBranch < ActiveRecord::Migration + def self.up + add_column :changes, :branch, :string + end + + def self.down + remove_column :changes, :branch + end +end diff --git a/db/migrate/054_add_changesets_scmid.rb b/db/migrate/054_add_changesets_scmid.rb new file mode 100644 index 000000000..188fa6ef6 --- /dev/null +++ b/db/migrate/054_add_changesets_scmid.rb @@ -0,0 +1,9 @@ +class AddChangesetsScmid < ActiveRecord::Migration + def self.up + add_column :changesets, :scmid, :string + end + + def self.down + remove_column :changesets, :scmid + end +end diff --git a/db/migrate/055_add_repositories_type.rb b/db/migrate/055_add_repositories_type.rb new file mode 100644 index 000000000..f5a71620c --- /dev/null +++ b/db/migrate/055_add_repositories_type.rb @@ -0,0 +1,11 @@ +class AddRepositoriesType < ActiveRecord::Migration + def self.up + add_column :repositories, :type, :string + # Set class name for existing SVN repositories + Repository.update_all "type = 'Subversion'" + end + + def self.down + remove_column :repositories, :type + end +end diff --git a/db/migrate/056_add_repositories_changes_permission.rb b/db/migrate/056_add_repositories_changes_permission.rb new file mode 100644 index 000000000..0d9b13b59 --- /dev/null +++ b/db/migrate/056_add_repositories_changes_permission.rb @@ -0,0 +1,12 @@ +class AddRepositoriesChangesPermission < ActiveRecord::Migration + # model removed + class Permission < ActiveRecord::Base; end + + def self.up + Permission.create :controller => 'repositories', :action => 'changes', :description => 'label_change_plural', :sort => 1475, :is_public => true, :mail_option => 0, :mail_enabled => 0 + end + + def self.down + Permission.find_by_controller_and_action('repositories', 'changes').destroy + end +end diff --git a/db/migrate/057_add_versions_wiki_page_title.rb b/db/migrate/057_add_versions_wiki_page_title.rb new file mode 100644 index 000000000..58b8fd9a8 --- /dev/null +++ b/db/migrate/057_add_versions_wiki_page_title.rb @@ -0,0 +1,9 @@ +class AddVersionsWikiPageTitle < ActiveRecord::Migration + def self.up + add_column :versions, :wiki_page_title, :string + end + + def self.down + remove_column :versions, :wiki_page_title + end +end diff --git a/db/migrate/058_add_issue_categories_assigned_to_id.rb b/db/migrate/058_add_issue_categories_assigned_to_id.rb new file mode 100644 index 000000000..8653532e0 --- /dev/null +++ b/db/migrate/058_add_issue_categories_assigned_to_id.rb @@ -0,0 +1,9 @@ +class AddIssueCategoriesAssignedToId < ActiveRecord::Migration + def self.up + add_column :issue_categories, :assigned_to_id, :integer + end + + def self.down + remove_column :issue_categories, :assigned_to_id + end +end diff --git a/db/migrate/059_add_roles_assignable.rb b/db/migrate/059_add_roles_assignable.rb new file mode 100644 index 000000000..a1ba79634 --- /dev/null +++ b/db/migrate/059_add_roles_assignable.rb @@ -0,0 +1,9 @@ +class AddRolesAssignable < ActiveRecord::Migration + def self.up + add_column :roles, :assignable, :boolean, :default => true + end + + def self.down + remove_column :roles, :assignable + end +end diff --git a/db/migrate/060_change_changesets_committer_limit.rb b/db/migrate/060_change_changesets_committer_limit.rb new file mode 100644 index 000000000..b05096379 --- /dev/null +++ b/db/migrate/060_change_changesets_committer_limit.rb @@ -0,0 +1,9 @@ +class ChangeChangesetsCommitterLimit < ActiveRecord::Migration + def self.up + change_column :changesets, :committer, :string, :limit => nil + end + + def self.down + change_column :changesets, :committer, :string, :limit => 30 + end +end diff --git a/db/migrate/061_add_roles_builtin.rb b/db/migrate/061_add_roles_builtin.rb new file mode 100644 index 000000000..a8d6fe9e6 --- /dev/null +++ b/db/migrate/061_add_roles_builtin.rb @@ -0,0 +1,9 @@ +class AddRolesBuiltin < ActiveRecord::Migration + def self.up + add_column :roles, :builtin, :integer, :default => 0, :null => false + end + + def self.down + remove_column :roles, :builtin + end +end diff --git a/db/migrate/062_insert_builtin_roles.rb b/db/migrate/062_insert_builtin_roles.rb new file mode 100644 index 000000000..070d9285f --- /dev/null +++ b/db/migrate/062_insert_builtin_roles.rb @@ -0,0 +1,16 @@ +class InsertBuiltinRoles < ActiveRecord::Migration + def self.up + Role.reset_column_information + 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 --git a/db/migrate/063_add_roles_permissions.rb b/db/migrate/063_add_roles_permissions.rb new file mode 100644 index 000000000..107a3af0a --- /dev/null +++ b/db/migrate/063_add_roles_permissions.rb @@ -0,0 +1,9 @@ +class AddRolesPermissions < ActiveRecord::Migration + def self.up + add_column :roles, :permissions, :text + end + + def self.down + remove_column :roles, :permissions + end +end diff --git a/db/migrate/064_drop_permissions.rb b/db/migrate/064_drop_permissions.rb new file mode 100644 index 000000000..f4ca470bf --- /dev/null +++ b/db/migrate/064_drop_permissions.rb @@ -0,0 +1,10 @@ +class DropPermissions < ActiveRecord::Migration + def self.up + drop_table :permissions + drop_table :permissions_roles + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/065_add_settings_updated_on.rb b/db/migrate/065_add_settings_updated_on.rb new file mode 100644 index 000000000..1fa002776 --- /dev/null +++ b/db/migrate/065_add_settings_updated_on.rb @@ -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 --git a/db/migrate/066_add_custom_value_customized_index.rb b/db/migrate/066_add_custom_value_customized_index.rb new file mode 100644 index 000000000..1f4c40da2 --- /dev/null +++ b/db/migrate/066_add_custom_value_customized_index.rb @@ -0,0 +1,9 @@ +class AddCustomValueCustomizedIndex < ActiveRecord::Migration + def self.up + add_index :custom_values, [:customized_type, :customized_id], :name => :custom_values_customized + end + + def self.down + remove_index :custom_values, :name => :custom_values_customized + end +end diff --git a/db/migrate/067_create_wiki_redirects.rb b/db/migrate/067_create_wiki_redirects.rb new file mode 100644 index 000000000..dda6ba6d5 --- /dev/null +++ b/db/migrate/067_create_wiki_redirects.rb @@ -0,0 +1,15 @@ +class CreateWikiRedirects < ActiveRecord::Migration + def self.up + create_table :wiki_redirects do |t| + t.column :wiki_id, :integer, :null => false + t.column :title, :string + t.column :redirects_to, :string + t.column :created_on, :datetime, :null => false + end + add_index :wiki_redirects, [:wiki_id, :title], :name => :wiki_redirects_wiki_id_title + end + + def self.down + drop_table :wiki_redirects + end +end diff --git a/db/migrate/068_create_enabled_modules.rb b/db/migrate/068_create_enabled_modules.rb new file mode 100644 index 000000000..88005cdb6 --- /dev/null +++ b/db/migrate/068_create_enabled_modules.rb @@ -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 --git a/db/migrate/069_add_issues_estimated_hours.rb b/db/migrate/069_add_issues_estimated_hours.rb new file mode 100644 index 000000000..90b86e243 --- /dev/null +++ b/db/migrate/069_add_issues_estimated_hours.rb @@ -0,0 +1,9 @@ +class AddIssuesEstimatedHours < ActiveRecord::Migration + def self.up + add_column :issues, :estimated_hours, :float + end + + def self.down + remove_column :issues, :estimated_hours + end +end diff --git a/db/migrate/070_change_attachments_content_type_limit.rb b/db/migrate/070_change_attachments_content_type_limit.rb new file mode 100644 index 000000000..ebf6d08c3 --- /dev/null +++ b/db/migrate/070_change_attachments_content_type_limit.rb @@ -0,0 +1,9 @@ +class ChangeAttachmentsContentTypeLimit < ActiveRecord::Migration + def self.up + change_column :attachments, :content_type, :string, :limit => nil + end + + def self.down + change_column :attachments, :content_type, :string, :limit => 60 + end +end diff --git a/db/migrate/071_add_queries_column_names.rb b/db/migrate/071_add_queries_column_names.rb new file mode 100644 index 000000000..acaf4dab0 --- /dev/null +++ b/db/migrate/071_add_queries_column_names.rb @@ -0,0 +1,9 @@ +class AddQueriesColumnNames < ActiveRecord::Migration + def self.up + add_column :queries, :column_names, :text + end + + def self.down + remove_column :queries, :column_names + end +end diff --git a/db/migrate/072_add_enumerations_position.rb b/db/migrate/072_add_enumerations_position.rb new file mode 100644 index 000000000..98092e5cf --- /dev/null +++ b/db/migrate/072_add_enumerations_position.rb @@ -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 --git a/db/migrate/073_add_enumerations_is_default.rb b/db/migrate/073_add_enumerations_is_default.rb new file mode 100644 index 000000000..7365a1411 --- /dev/null +++ b/db/migrate/073_add_enumerations_is_default.rb @@ -0,0 +1,9 @@ +class AddEnumerationsIsDefault < ActiveRecord::Migration + def self.up + add_column :enumerations, :is_default, :boolean, :default => false, :null => false + end + + def self.down + remove_column :enumerations, :is_default + end +end diff --git a/db/migrate/074_add_auth_sources_tls.rb b/db/migrate/074_add_auth_sources_tls.rb new file mode 100644 index 000000000..3987f7036 --- /dev/null +++ b/db/migrate/074_add_auth_sources_tls.rb @@ -0,0 +1,9 @@ +class AddAuthSourcesTls < ActiveRecord::Migration + def self.up + add_column :auth_sources, :tls, :boolean, :default => false, :null => false + end + + def self.down + remove_column :auth_sources, :tls + end +end diff --git a/db/migrate/075_add_members_mail_notification.rb b/db/migrate/075_add_members_mail_notification.rb new file mode 100644 index 000000000..d83ba8dd0 --- /dev/null +++ b/db/migrate/075_add_members_mail_notification.rb @@ -0,0 +1,9 @@ +class AddMembersMailNotification < ActiveRecord::Migration + def self.up + add_column :members, :mail_notification, :boolean, :default => false, :null => false + end + + def self.down + remove_column :members, :mail_notification + end +end diff --git a/db/migrate/076_allow_null_position.rb b/db/migrate/076_allow_null_position.rb new file mode 100644 index 000000000..ece0370db --- /dev/null +++ b/db/migrate/076_allow_null_position.rb @@ -0,0 +1,14 @@ +class AllowNullPosition < ActiveRecord::Migration + def self.up + # removes the 'not null' constraint on position fields + change_column :issue_statuses, :position, :integer, :default => 1, :null => true + change_column :roles, :position, :integer, :default => 1, :null => true + change_column :trackers, :position, :integer, :default => 1, :null => true + change_column :boards, :position, :integer, :default => 1, :null => true + change_column :enumerations, :position, :integer, :default => 1, :null => true + end + + def self.down + # nothing to do + end +end diff --git a/db/migrate/077_remove_issue_statuses_html_color.rb b/db/migrate/077_remove_issue_statuses_html_color.rb new file mode 100644 index 000000000..a3e2c3f8f --- /dev/null +++ b/db/migrate/077_remove_issue_statuses_html_color.rb @@ -0,0 +1,9 @@ +class RemoveIssueStatusesHtmlColor < ActiveRecord::Migration + def self.up + remove_column :issue_statuses, :html_color + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/078_add_custom_fields_position.rb b/db/migrate/078_add_custom_fields_position.rb new file mode 100644 index 000000000..cb29098fd --- /dev/null +++ b/db/migrate/078_add_custom_fields_position.rb @@ -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 --git a/db/migrate/079_add_user_preferences_time_zone.rb b/db/migrate/079_add_user_preferences_time_zone.rb new file mode 100644 index 000000000..9e36790a9 --- /dev/null +++ b/db/migrate/079_add_user_preferences_time_zone.rb @@ -0,0 +1,9 @@ +class AddUserPreferencesTimeZone < ActiveRecord::Migration + def self.up + add_column :user_preferences, :time_zone, :string + end + + def self.down + remove_column :user_preferences, :time_zone + end +end diff --git a/db/migrate/080_add_users_type.rb b/db/migrate/080_add_users_type.rb new file mode 100644 index 000000000..c907b472e --- /dev/null +++ b/db/migrate/080_add_users_type.rb @@ -0,0 +1,10 @@ +class AddUsersType < ActiveRecord::Migration + def self.up + add_column :users, :type, :string + User.update_all "type = 'User'" + end + + def self.down + remove_column :users, :type + end +end diff --git a/db/migrate/081_create_projects_trackers.rb b/db/migrate/081_create_projects_trackers.rb new file mode 100644 index 000000000..ddb801d31 --- /dev/null +++ b/db/migrate/081_create_projects_trackers.rb @@ -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 --git a/db/migrate/082_add_messages_locked.rb b/db/migrate/082_add_messages_locked.rb new file mode 100644 index 000000000..20a172565 --- /dev/null +++ b/db/migrate/082_add_messages_locked.rb @@ -0,0 +1,9 @@ +class AddMessagesLocked < ActiveRecord::Migration + def self.up + add_column :messages, :locked, :boolean, :default => false + end + + def self.down + remove_column :messages, :locked + end +end diff --git a/db/migrate/083_add_messages_sticky.rb b/db/migrate/083_add_messages_sticky.rb new file mode 100644 index 000000000..8fd5d2ce3 --- /dev/null +++ b/db/migrate/083_add_messages_sticky.rb @@ -0,0 +1,9 @@ +class AddMessagesSticky < ActiveRecord::Migration + def self.up + add_column :messages, :sticky, :integer, :default => 0 + end + + def self.down + remove_column :messages, :sticky + end +end diff --git a/db/migrate/084_change_auth_sources_account_limit.rb b/db/migrate/084_change_auth_sources_account_limit.rb new file mode 100644 index 000000000..cc127b439 --- /dev/null +++ b/db/migrate/084_change_auth_sources_account_limit.rb @@ -0,0 +1,9 @@ +class ChangeAuthSourcesAccountLimit < ActiveRecord::Migration + def self.up + change_column :auth_sources, :account, :string, :limit => nil + end + + def self.down + change_column :auth_sources, :account, :string, :limit => 60 + end +end diff --git a/db/migrate/085_add_role_tracker_old_status_index_to_workflows.rb b/db/migrate/085_add_role_tracker_old_status_index_to_workflows.rb new file mode 100644 index 000000000..a59135be0 --- /dev/null +++ b/db/migrate/085_add_role_tracker_old_status_index_to_workflows.rb @@ -0,0 +1,9 @@ +class AddRoleTrackerOldStatusIndexToWorkflows < ActiveRecord::Migration + def self.up + add_index :workflows, [:role_id, :tracker_id, :old_status_id], :name => :wkfs_role_tracker_old_status + end + + def self.down + remove_index(:workflows, :name => :wkfs_role_tracker_old_status); rescue + end +end diff --git a/db/migrate/086_add_custom_fields_searchable.rb b/db/migrate/086_add_custom_fields_searchable.rb new file mode 100644 index 000000000..53158d14e --- /dev/null +++ b/db/migrate/086_add_custom_fields_searchable.rb @@ -0,0 +1,9 @@ +class AddCustomFieldsSearchable < ActiveRecord::Migration + def self.up + add_column :custom_fields, :searchable, :boolean, :default => false + end + + def self.down + remove_column :custom_fields, :searchable + end +end diff --git a/db/migrate/087_change_projects_description_to_text.rb b/db/migrate/087_change_projects_description_to_text.rb new file mode 100644 index 000000000..132e921b3 --- /dev/null +++ b/db/migrate/087_change_projects_description_to_text.rb @@ -0,0 +1,8 @@ +class ChangeProjectsDescriptionToText < ActiveRecord::Migration + def self.up + change_column :projects, :description, :text, :null => true, :default => nil + end + + def self.down + end +end diff --git a/db/migrate/088_add_custom_fields_default_value.rb b/db/migrate/088_add_custom_fields_default_value.rb new file mode 100644 index 000000000..33a39ec6e --- /dev/null +++ b/db/migrate/088_add_custom_fields_default_value.rb @@ -0,0 +1,9 @@ +class AddCustomFieldsDefaultValue < ActiveRecord::Migration + def self.up + add_column :custom_fields, :default_value, :text + end + + def self.down + remove_column :custom_fields, :default_value + end +end diff --git a/db/migrate/089_add_attachments_description.rb b/db/migrate/089_add_attachments_description.rb new file mode 100644 index 000000000..411dfe4d6 --- /dev/null +++ b/db/migrate/089_add_attachments_description.rb @@ -0,0 +1,9 @@ +class AddAttachmentsDescription < ActiveRecord::Migration + def self.up + add_column :attachments, :description, :string + end + + def self.down + remove_column :attachments, :description + end +end diff --git a/db/migrate/090_change_versions_name_limit.rb b/db/migrate/090_change_versions_name_limit.rb new file mode 100644 index 000000000..276429727 --- /dev/null +++ b/db/migrate/090_change_versions_name_limit.rb @@ -0,0 +1,9 @@ +class ChangeVersionsNameLimit < ActiveRecord::Migration + def self.up + change_column :versions, :name, :string, :limit => nil + end + + def self.down + change_column :versions, :name, :string, :limit => 30 + end +end diff --git a/db/migrate/091_change_changesets_revision_to_string.rb b/db/migrate/091_change_changesets_revision_to_string.rb new file mode 100644 index 000000000..64988069d --- /dev/null +++ b/db/migrate/091_change_changesets_revision_to_string.rb @@ -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 --git a/db/migrate/092_change_changes_from_revision_to_string.rb b/db/migrate/092_change_changes_from_revision_to_string.rb new file mode 100644 index 000000000..b298a3f45 --- /dev/null +++ b/db/migrate/092_change_changes_from_revision_to_string.rb @@ -0,0 +1,9 @@ +class ChangeChangesFromRevisionToString < ActiveRecord::Migration + def self.up + change_column :changes, :from_revision, :string + end + + def self.down + change_column :changes, :from_revision, :integer + end +end diff --git a/db/migrate/093_add_wiki_pages_protected.rb b/db/migrate/093_add_wiki_pages_protected.rb new file mode 100644 index 000000000..49720fbb7 --- /dev/null +++ b/db/migrate/093_add_wiki_pages_protected.rb @@ -0,0 +1,9 @@ +class AddWikiPagesProtected < ActiveRecord::Migration + def self.up + add_column :wiki_pages, :protected, :boolean, :default => false, :null => false + end + + def self.down + remove_column :wiki_pages, :protected + end +end diff --git a/db/migrate/094_change_projects_homepage_limit.rb b/db/migrate/094_change_projects_homepage_limit.rb new file mode 100644 index 000000000..98374aa4e --- /dev/null +++ b/db/migrate/094_change_projects_homepage_limit.rb @@ -0,0 +1,9 @@ +class ChangeProjectsHomepageLimit < ActiveRecord::Migration + def self.up + change_column :projects, :homepage, :string, :limit => nil, :default => '' + end + + def self.down + change_column :projects, :homepage, :string, :limit => 60, :default => '' + end +end diff --git a/db/migrate/095_add_wiki_pages_parent_id.rb b/db/migrate/095_add_wiki_pages_parent_id.rb new file mode 100644 index 000000000..36b922ec1 --- /dev/null +++ b/db/migrate/095_add_wiki_pages_parent_id.rb @@ -0,0 +1,9 @@ +class AddWikiPagesParentId < ActiveRecord::Migration + def self.up + add_column :wiki_pages, :parent_id, :integer, :default => nil + end + + def self.down + remove_column :wiki_pages, :parent_id + end +end diff --git a/db/migrate/096_add_commit_access_permission.rb b/db/migrate/096_add_commit_access_permission.rb new file mode 100644 index 000000000..39642cdfe --- /dev/null +++ b/db/migrate/096_add_commit_access_permission.rb @@ -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 --git a/db/migrate/097_add_view_wiki_edits_permission.rb b/db/migrate/097_add_view_wiki_edits_permission.rb new file mode 100644 index 000000000..cd25f3cb1 --- /dev/null +++ b/db/migrate/097_add_view_wiki_edits_permission.rb @@ -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 --git a/db/migrate/098_set_topic_authors_as_watchers.rb b/db/migrate/098_set_topic_authors_as_watchers.rb new file mode 100644 index 000000000..92a53f4a1 --- /dev/null +++ b/db/migrate/098_set_topic_authors_as_watchers.rb @@ -0,0 +1,15 @@ +class SetTopicAuthorsAsWatchers < ActiveRecord::Migration + def self.up + # Sets active users who created/replied a topic as watchers of the topic + # so that the new watch functionality at topic level doesn't affect notifications behaviour + Message.connection.execute("INSERT INTO #{Watcher.table_name} (watchable_type, watchable_id, user_id)" + + " SELECT DISTINCT 'Message', COALESCE(m.parent_id, m.id), m.author_id" + + " FROM #{Message.table_name} m, #{User.table_name} u" + + " WHERE m.author_id = u.id AND u.status = 1") + end + + def self.down + # Removes all message watchers + Watcher.delete_all("watchable_type = 'Message'") + end +end diff --git a/db/migrate/099_add_delete_wiki_pages_attachments_permission.rb b/db/migrate/099_add_delete_wiki_pages_attachments_permission.rb new file mode 100644 index 000000000..475e4d0aa --- /dev/null +++ b/db/migrate/099_add_delete_wiki_pages_attachments_permission.rb @@ -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 --git a/db/migrate/100_add_changesets_user_id.rb b/db/migrate/100_add_changesets_user_id.rb new file mode 100644 index 000000000..9b25fd7bc --- /dev/null +++ b/db/migrate/100_add_changesets_user_id.rb @@ -0,0 +1,9 @@ +class AddChangesetsUserId < ActiveRecord::Migration + def self.up + add_column :changesets, :user_id, :integer, :default => nil + end + + def self.down + remove_column :changesets, :user_id + end +end diff --git a/db/migrate/101_populate_changesets_user_id.rb b/db/migrate/101_populate_changesets_user_id.rb new file mode 100644 index 000000000..dd493d17d --- /dev/null +++ b/db/migrate/101_populate_changesets_user_id.rb @@ -0,0 +1,18 @@ +class PopulateChangesetsUserId < ActiveRecord::Migration + def self.up + committers = Changeset.connection.select_values("SELECT DISTINCT committer FROM #{Changeset.table_name}") + committers.each do |committer| + next if committer.blank? + if committer.strip =~ /^([^<]+)(<(.*)>)?$/ + username, email = $1.strip, $3 + u = User.find_by_login(username) + u ||= User.find_by_mail(email) unless email.blank? + Changeset.update_all("user_id = #{u.id}", ["committer = ?", committer]) unless u.nil? + end + end + end + + def self.down + Changeset.update_all('user_id = NULL') + end +end diff --git a/db/migrate/102_add_custom_fields_editable.rb b/db/migrate/102_add_custom_fields_editable.rb new file mode 100644 index 000000000..949f9db9d --- /dev/null +++ b/db/migrate/102_add_custom_fields_editable.rb @@ -0,0 +1,9 @@ +class AddCustomFieldsEditable < ActiveRecord::Migration + def self.up + add_column :custom_fields, :editable, :boolean, :default => true + end + + def self.down + remove_column :custom_fields, :editable + end +end diff --git a/db/migrate/103_set_custom_fields_editable.rb b/db/migrate/103_set_custom_fields_editable.rb new file mode 100644 index 000000000..937649e61 --- /dev/null +++ b/db/migrate/103_set_custom_fields_editable.rb @@ -0,0 +1,9 @@ +class SetCustomFieldsEditable < ActiveRecord::Migration + def self.up + UserCustomField.update_all("editable = #{CustomField.connection.quoted_false}") + end + + def self.down + UserCustomField.update_all("editable = #{CustomField.connection.quoted_true}") + end +end diff --git a/db/migrate/104_add_projects_lft_and_rgt.rb b/db/migrate/104_add_projects_lft_and_rgt.rb new file mode 100644 index 000000000..8952c16e1 --- /dev/null +++ b/db/migrate/104_add_projects_lft_and_rgt.rb @@ -0,0 +1,11 @@ +class AddProjectsLftAndRgt < ActiveRecord::Migration + def self.up + add_column :projects, :lft, :integer + add_column :projects, :rgt, :integer + end + + def self.down + remove_column :projects, :lft + remove_column :projects, :rgt + end +end diff --git a/db/migrate/105_build_projects_tree.rb b/db/migrate/105_build_projects_tree.rb new file mode 100644 index 000000000..cd35373c0 --- /dev/null +++ b/db/migrate/105_build_projects_tree.rb @@ -0,0 +1,8 @@ +class BuildProjectsTree < ActiveRecord::Migration + def self.up + Project.rebuild_tree! + end + + def self.down + end +end diff --git a/db/migrate/106_remove_projects_projects_count.rb b/db/migrate/106_remove_projects_projects_count.rb new file mode 100644 index 000000000..68bb3d115 --- /dev/null +++ b/db/migrate/106_remove_projects_projects_count.rb @@ -0,0 +1,9 @@ +class RemoveProjectsProjectsCount < ActiveRecord::Migration + def self.up + remove_column :projects, :projects_count + end + + def self.down + add_column :projects, :projects_count, :integer, :default => 0 + end +end diff --git a/db/migrate/107_add_open_id_authentication_tables.rb b/db/migrate/107_add_open_id_authentication_tables.rb new file mode 100644 index 000000000..caae0d8c7 --- /dev/null +++ b/db/migrate/107_add_open_id_authentication_tables.rb @@ -0,0 +1,20 @@ +class AddOpenIdAuthenticationTables < ActiveRecord::Migration + def self.up + create_table :open_id_authentication_associations, :force => true do |t| + t.integer :issued, :lifetime + t.string :handle, :assoc_type + t.binary :server_url, :secret + end + + create_table :open_id_authentication_nonces, :force => true do |t| + t.integer :timestamp, :null => false + t.string :server_url, :null => true + t.string :salt, :null => false + end + end + + def self.down + drop_table :open_id_authentication_associations + drop_table :open_id_authentication_nonces + end +end diff --git a/db/migrate/108_add_identity_url_to_users.rb b/db/migrate/108_add_identity_url_to_users.rb new file mode 100644 index 000000000..f5af77b24 --- /dev/null +++ b/db/migrate/108_add_identity_url_to_users.rb @@ -0,0 +1,9 @@ +class AddIdentityUrlToUsers < ActiveRecord::Migration + def self.up + add_column :users, :identity_url, :string + end + + def self.down + remove_column :users, :identity_url + end +end diff --git a/db/migrate/20090214190337_add_watchers_user_id_type_index.rb b/db/migrate/20090214190337_add_watchers_user_id_type_index.rb new file mode 100644 index 000000000..7ff4e542c --- /dev/null +++ b/db/migrate/20090214190337_add_watchers_user_id_type_index.rb @@ -0,0 +1,9 @@ +class AddWatchersUserIdTypeIndex < ActiveRecord::Migration + def self.up + add_index :watchers, [:user_id, :watchable_type], :name => :watchers_user_id_type + end + + def self.down + remove_index :watchers, :name => :watchers_user_id_type + end +end diff --git a/db/migrate/20090312172426_add_queries_sort_criteria.rb b/db/migrate/20090312172426_add_queries_sort_criteria.rb new file mode 100644 index 000000000..743ed42ff --- /dev/null +++ b/db/migrate/20090312172426_add_queries_sort_criteria.rb @@ -0,0 +1,9 @@ +class AddQueriesSortCriteria < ActiveRecord::Migration + def self.up + add_column :queries, :sort_criteria, :text + end + + def self.down + remove_column :queries, :sort_criteria + end +end diff --git a/db/migrate/20090312194159_add_projects_trackers_unique_index.rb b/db/migrate/20090312194159_add_projects_trackers_unique_index.rb new file mode 100644 index 000000000..f4e3a26d2 --- /dev/null +++ b/db/migrate/20090312194159_add_projects_trackers_unique_index.rb @@ -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 --git a/db/migrate/20090318181151_extend_settings_name.rb b/db/migrate/20090318181151_extend_settings_name.rb new file mode 100644 index 000000000..eca03d555 --- /dev/null +++ b/db/migrate/20090318181151_extend_settings_name.rb @@ -0,0 +1,9 @@ +class ExtendSettingsName < ActiveRecord::Migration + def self.up + change_column :settings, :name, :string, :limit => 255, :default => '', :null => false + end + + def self.down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20090323224724_add_type_to_enumerations.rb b/db/migrate/20090323224724_add_type_to_enumerations.rb new file mode 100644 index 000000000..c2aef5e4a --- /dev/null +++ b/db/migrate/20090323224724_add_type_to_enumerations.rb @@ -0,0 +1,9 @@ +class AddTypeToEnumerations < ActiveRecord::Migration + def self.up + add_column :enumerations, :type, :string + end + + def self.down + remove_column :enumerations, :type + end +end diff --git a/db/migrate/20090401221305_update_enumerations_to_sti.rb b/db/migrate/20090401221305_update_enumerations_to_sti.rb new file mode 100644 index 000000000..50bd52010 --- /dev/null +++ b/db/migrate/20090401221305_update_enumerations_to_sti.rb @@ -0,0 +1,11 @@ +class UpdateEnumerationsToSti < ActiveRecord::Migration + def self.up + Enumeration.update_all("type = 'IssuePriority'", "opt = 'IPRI'") + Enumeration.update_all("type = 'DocumentCategory'", "opt = 'DCAT'") + Enumeration.update_all("type = 'TimeEntryActivity'", "opt = 'ACTI'") + end + + def self.down + # no-op + end +end diff --git a/db/migrate/20090401231134_add_active_field_to_enumerations.rb b/db/migrate/20090401231134_add_active_field_to_enumerations.rb new file mode 100644 index 000000000..55824fa65 --- /dev/null +++ b/db/migrate/20090401231134_add_active_field_to_enumerations.rb @@ -0,0 +1,9 @@ +class AddActiveFieldToEnumerations < ActiveRecord::Migration + def self.up + add_column :enumerations, :active, :boolean, :default => true, :null => false + end + + def self.down + remove_column :enumerations, :active + end +end diff --git a/db/migrate/20090403001910_add_project_to_enumerations.rb b/db/migrate/20090403001910_add_project_to_enumerations.rb new file mode 100644 index 000000000..a3db6d51e --- /dev/null +++ b/db/migrate/20090403001910_add_project_to_enumerations.rb @@ -0,0 +1,11 @@ +class AddProjectToEnumerations < ActiveRecord::Migration + def self.up + add_column :enumerations, :project_id, :integer, :null => true, :default => nil + add_index :enumerations, :project_id + end + + def self.down + remove_index :enumerations, :project_id + remove_column :enumerations, :project_id + end +end diff --git a/db/migrate/20090406161854_add_parent_id_to_enumerations.rb b/db/migrate/20090406161854_add_parent_id_to_enumerations.rb new file mode 100644 index 000000000..2c1b1780d --- /dev/null +++ b/db/migrate/20090406161854_add_parent_id_to_enumerations.rb @@ -0,0 +1,9 @@ +class AddParentIdToEnumerations < ActiveRecord::Migration + def self.up + add_column :enumerations, :parent_id, :integer, :null => true, :default => nil + end + + def self.down + remove_column :enumerations, :parent_id + end +end diff --git a/db/migrate/20090425161243_add_queries_group_by.rb b/db/migrate/20090425161243_add_queries_group_by.rb new file mode 100644 index 000000000..1405f3d0b --- /dev/null +++ b/db/migrate/20090425161243_add_queries_group_by.rb @@ -0,0 +1,9 @@ +class AddQueriesGroupBy < ActiveRecord::Migration + def self.up + add_column :queries, :group_by, :string + end + + def self.down + remove_column :queries, :group_by + end +end diff --git a/db/migrate/20090503121501_create_member_roles.rb b/db/migrate/20090503121501_create_member_roles.rb new file mode 100644 index 000000000..38519ea7c --- /dev/null +++ b/db/migrate/20090503121501_create_member_roles.rb @@ -0,0 +1,12 @@ +class CreateMemberRoles < ActiveRecord::Migration + def self.up + create_table :member_roles do |t| + t.column :member_id, :integer, :null => false + t.column :role_id, :integer, :null => false + end + end + + def self.down + drop_table :member_roles + end +end diff --git a/db/migrate/20090503121505_populate_member_roles.rb b/db/migrate/20090503121505_populate_member_roles.rb new file mode 100644 index 000000000..285d7e51a --- /dev/null +++ b/db/migrate/20090503121505_populate_member_roles.rb @@ -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 --git a/db/migrate/20090503121510_drop_members_role_id.rb b/db/migrate/20090503121510_drop_members_role_id.rb new file mode 100644 index 000000000..c28119910 --- /dev/null +++ b/db/migrate/20090503121510_drop_members_role_id.rb @@ -0,0 +1,9 @@ +class DropMembersRoleId < ActiveRecord::Migration + def self.up + remove_column :members, :role_id + end + + def self.down + raise IrreversibleMigration + end +end diff --git a/db/migrate/20090614091200_fix_messages_sticky_null.rb b/db/migrate/20090614091200_fix_messages_sticky_null.rb new file mode 100644 index 000000000..cbe741732 --- /dev/null +++ b/db/migrate/20090614091200_fix_messages_sticky_null.rb @@ -0,0 +1,9 @@ +class FixMessagesStickyNull < ActiveRecord::Migration + def self.up + Message.update_all('sticky = 0', 'sticky IS NULL') + end + + def self.down + # nothing to do + end +end diff --git a/db/migrate/20090704172350_populate_users_type.rb b/db/migrate/20090704172350_populate_users_type.rb new file mode 100644 index 000000000..1c31feced --- /dev/null +++ b/db/migrate/20090704172350_populate_users_type.rb @@ -0,0 +1,8 @@ +class PopulateUsersType < ActiveRecord::Migration + def self.up + Principal.update_all("type = 'User'", "type IS NULL") + end + + def self.down + end +end diff --git a/db/migrate/20090704172355_create_groups_users.rb b/db/migrate/20090704172355_create_groups_users.rb new file mode 100644 index 000000000..9ce03b95b --- /dev/null +++ b/db/migrate/20090704172355_create_groups_users.rb @@ -0,0 +1,13 @@ +class CreateGroupsUsers < ActiveRecord::Migration + def self.up + create_table :groups_users, :id => false do |t| + t.column :group_id, :integer, :null => false + t.column :user_id, :integer, :null => false + end + add_index :groups_users, [:group_id, :user_id], :unique => true, :name => :groups_users_ids + end + + def self.down + drop_table :groups_users + end +end diff --git a/db/migrate/20090704172358_add_member_roles_inherited_from.rb b/db/migrate/20090704172358_add_member_roles_inherited_from.rb new file mode 100644 index 000000000..4ffa52389 --- /dev/null +++ b/db/migrate/20090704172358_add_member_roles_inherited_from.rb @@ -0,0 +1,9 @@ +class AddMemberRolesInheritedFrom < ActiveRecord::Migration + def self.up + add_column :member_roles, :inherited_from, :integer + end + + def self.down + remove_column :member_roles, :inherited_from + end +end diff --git a/db/migrate/20091010093521_fix_users_custom_values.rb b/db/migrate/20091010093521_fix_users_custom_values.rb new file mode 100644 index 000000000..923c78fc0 --- /dev/null +++ b/db/migrate/20091010093521_fix_users_custom_values.rb @@ -0,0 +1,9 @@ +class FixUsersCustomValues < ActiveRecord::Migration + def self.up + CustomValue.update_all("customized_type = 'Principal'", "customized_type = 'User'") + end + + def self.down + CustomValue.update_all("customized_type = 'User'", "customized_type = 'Principal'") + end +end diff --git a/db/migrate/20091017212227_add_missing_indexes_to_workflows.rb b/db/migrate/20091017212227_add_missing_indexes_to_workflows.rb new file mode 100644 index 000000000..13fa0137e --- /dev/null +++ b/db/migrate/20091017212227_add_missing_indexes_to_workflows.rb @@ -0,0 +1,13 @@ +class AddMissingIndexesToWorkflows < ActiveRecord::Migration + def self.up + add_index :workflows, :old_status_id + add_index :workflows, :role_id + add_index :workflows, :new_status_id + end + + def self.down + remove_index :workflows, :old_status_id + remove_index :workflows, :role_id + remove_index :workflows, :new_status_id + end +end diff --git a/db/migrate/20091017212457_add_missing_indexes_to_custom_fields_projects.rb b/db/migrate/20091017212457_add_missing_indexes_to_custom_fields_projects.rb new file mode 100644 index 000000000..b95f54327 --- /dev/null +++ b/db/migrate/20091017212457_add_missing_indexes_to_custom_fields_projects.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToCustomFieldsProjects < ActiveRecord::Migration + def self.up + add_index :custom_fields_projects, [:custom_field_id, :project_id] + end + + def self.down + remove_index :custom_fields_projects, :column => [:custom_field_id, :project_id] + end +end diff --git a/db/migrate/20091017212644_add_missing_indexes_to_messages.rb b/db/migrate/20091017212644_add_missing_indexes_to_messages.rb new file mode 100644 index 000000000..23c272995 --- /dev/null +++ b/db/migrate/20091017212644_add_missing_indexes_to_messages.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToMessages < ActiveRecord::Migration + def self.up + add_index :messages, :last_reply_id + add_index :messages, :author_id + end + + def self.down + remove_index :messages, :last_reply_id + remove_index :messages, :author_id + end +end diff --git a/db/migrate/20091017212938_add_missing_indexes_to_repositories.rb b/db/migrate/20091017212938_add_missing_indexes_to_repositories.rb new file mode 100644 index 000000000..b9f43b6df --- /dev/null +++ b/db/migrate/20091017212938_add_missing_indexes_to_repositories.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToRepositories < ActiveRecord::Migration + def self.up + add_index :repositories, :project_id + end + + def self.down + remove_index :repositories, :project_id + end +end diff --git a/db/migrate/20091017213027_add_missing_indexes_to_comments.rb b/db/migrate/20091017213027_add_missing_indexes_to_comments.rb new file mode 100644 index 000000000..2a1ed27c0 --- /dev/null +++ b/db/migrate/20091017213027_add_missing_indexes_to_comments.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToComments < ActiveRecord::Migration + def self.up + add_index :comments, [:commented_id, :commented_type] + add_index :comments, :author_id + end + + def self.down + remove_index :comments, :column => [:commented_id, :commented_type] + remove_index :comments, :author_id + end +end diff --git a/db/migrate/20091017213113_add_missing_indexes_to_enumerations.rb b/db/migrate/20091017213113_add_missing_indexes_to_enumerations.rb new file mode 100644 index 000000000..85dedf816 --- /dev/null +++ b/db/migrate/20091017213113_add_missing_indexes_to_enumerations.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToEnumerations < ActiveRecord::Migration + def self.up + add_index :enumerations, [:id, :type] + end + + def self.down + remove_index :enumerations, :column => [:id, :type] + end +end diff --git a/db/migrate/20091017213151_add_missing_indexes_to_wiki_pages.rb b/db/migrate/20091017213151_add_missing_indexes_to_wiki_pages.rb new file mode 100644 index 000000000..7fab09e38 --- /dev/null +++ b/db/migrate/20091017213151_add_missing_indexes_to_wiki_pages.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToWikiPages < ActiveRecord::Migration + def self.up + add_index :wiki_pages, :wiki_id + add_index :wiki_pages, :parent_id + end + + def self.down + remove_index :wiki_pages, :wiki_id + remove_index :wiki_pages, :parent_id + end +end diff --git a/db/migrate/20091017213228_add_missing_indexes_to_watchers.rb b/db/migrate/20091017213228_add_missing_indexes_to_watchers.rb new file mode 100644 index 000000000..618e1cd94 --- /dev/null +++ b/db/migrate/20091017213228_add_missing_indexes_to_watchers.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToWatchers < ActiveRecord::Migration + def self.up + add_index :watchers, :user_id + add_index :watchers, [:watchable_id, :watchable_type] + end + + def self.down + remove_index :watchers, :user_id + remove_index :watchers, :column => [:watchable_id, :watchable_type] + end +end diff --git a/db/migrate/20091017213257_add_missing_indexes_to_auth_sources.rb b/db/migrate/20091017213257_add_missing_indexes_to_auth_sources.rb new file mode 100644 index 000000000..ccd4f0440 --- /dev/null +++ b/db/migrate/20091017213257_add_missing_indexes_to_auth_sources.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToAuthSources < ActiveRecord::Migration + def self.up + add_index :auth_sources, [:id, :type] + end + + def self.down + remove_index :auth_sources, :column => [:id, :type] + end +end diff --git a/db/migrate/20091017213332_add_missing_indexes_to_documents.rb b/db/migrate/20091017213332_add_missing_indexes_to_documents.rb new file mode 100644 index 000000000..f5190181e --- /dev/null +++ b/db/migrate/20091017213332_add_missing_indexes_to_documents.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToDocuments < ActiveRecord::Migration + def self.up + add_index :documents, :category_id + end + + def self.down + remove_index :documents, :category_id + end +end diff --git a/db/migrate/20091017213444_add_missing_indexes_to_tokens.rb b/db/migrate/20091017213444_add_missing_indexes_to_tokens.rb new file mode 100644 index 000000000..f0979f21c --- /dev/null +++ b/db/migrate/20091017213444_add_missing_indexes_to_tokens.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToTokens < ActiveRecord::Migration + def self.up + add_index :tokens, :user_id + end + + def self.down + remove_index :tokens, :user_id + end +end diff --git a/db/migrate/20091017213536_add_missing_indexes_to_changesets.rb b/db/migrate/20091017213536_add_missing_indexes_to_changesets.rb new file mode 100644 index 000000000..303be838d --- /dev/null +++ b/db/migrate/20091017213536_add_missing_indexes_to_changesets.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToChangesets < ActiveRecord::Migration + def self.up + add_index :changesets, :user_id + add_index :changesets, :repository_id + end + + def self.down + remove_index :changesets, :user_id + remove_index :changesets, :repository_id + end +end diff --git a/db/migrate/20091017213642_add_missing_indexes_to_issue_categories.rb b/db/migrate/20091017213642_add_missing_indexes_to_issue_categories.rb new file mode 100644 index 000000000..3f5b2b185 --- /dev/null +++ b/db/migrate/20091017213642_add_missing_indexes_to_issue_categories.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToIssueCategories < ActiveRecord::Migration + def self.up + add_index :issue_categories, :assigned_to_id + end + + def self.down + remove_index :issue_categories, :assigned_to_id + end +end diff --git a/db/migrate/20091017213716_add_missing_indexes_to_member_roles.rb b/db/migrate/20091017213716_add_missing_indexes_to_member_roles.rb new file mode 100644 index 000000000..e9ff62db9 --- /dev/null +++ b/db/migrate/20091017213716_add_missing_indexes_to_member_roles.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToMemberRoles < ActiveRecord::Migration + def self.up + add_index :member_roles, :member_id + add_index :member_roles, :role_id + end + + def self.down + remove_index :member_roles, :member_id + remove_index :member_roles, :role_id + end +end diff --git a/db/migrate/20091017213757_add_missing_indexes_to_boards.rb b/db/migrate/20091017213757_add_missing_indexes_to_boards.rb new file mode 100644 index 000000000..d3e94226a --- /dev/null +++ b/db/migrate/20091017213757_add_missing_indexes_to_boards.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToBoards < ActiveRecord::Migration + def self.up + add_index :boards, :last_message_id + end + + def self.down + remove_index :boards, :last_message_id + end +end diff --git a/db/migrate/20091017213835_add_missing_indexes_to_user_preferences.rb b/db/migrate/20091017213835_add_missing_indexes_to_user_preferences.rb new file mode 100644 index 000000000..f3a8ccbcb --- /dev/null +++ b/db/migrate/20091017213835_add_missing_indexes_to_user_preferences.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToUserPreferences < ActiveRecord::Migration + def self.up + add_index :user_preferences, :user_id + end + + def self.down + remove_index :user_preferences, :user_id + end +end diff --git a/db/migrate/20091017213910_add_missing_indexes_to_issues.rb b/db/migrate/20091017213910_add_missing_indexes_to_issues.rb new file mode 100644 index 000000000..d651a5463 --- /dev/null +++ b/db/migrate/20091017213910_add_missing_indexes_to_issues.rb @@ -0,0 +1,21 @@ +class AddMissingIndexesToIssues < ActiveRecord::Migration + def self.up + add_index :issues, :status_id + add_index :issues, :category_id + add_index :issues, :assigned_to_id + add_index :issues, :fixed_version_id + add_index :issues, :tracker_id + add_index :issues, :priority_id + add_index :issues, :author_id + end + + def self.down + remove_index :issues, :status_id + remove_index :issues, :category_id + remove_index :issues, :assigned_to_id + remove_index :issues, :fixed_version_id + remove_index :issues, :tracker_id + remove_index :issues, :priority_id + remove_index :issues, :author_id + end +end diff --git a/db/migrate/20091017214015_add_missing_indexes_to_members.rb b/db/migrate/20091017214015_add_missing_indexes_to_members.rb new file mode 100644 index 000000000..5fdf560fa --- /dev/null +++ b/db/migrate/20091017214015_add_missing_indexes_to_members.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToMembers < ActiveRecord::Migration + def self.up + add_index :members, :user_id + add_index :members, :project_id + end + + def self.down + remove_index :members, :user_id + remove_index :members, :project_id + end +end diff --git a/db/migrate/20091017214107_add_missing_indexes_to_custom_fields.rb b/db/migrate/20091017214107_add_missing_indexes_to_custom_fields.rb new file mode 100644 index 000000000..18be0b44b --- /dev/null +++ b/db/migrate/20091017214107_add_missing_indexes_to_custom_fields.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToCustomFields < ActiveRecord::Migration + def self.up + add_index :custom_fields, [:id, :type] + end + + def self.down + remove_index :custom_fields, :column => [:id, :type] + end +end diff --git a/db/migrate/20091017214136_add_missing_indexes_to_queries.rb b/db/migrate/20091017214136_add_missing_indexes_to_queries.rb new file mode 100644 index 000000000..414b1ad6b --- /dev/null +++ b/db/migrate/20091017214136_add_missing_indexes_to_queries.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToQueries < ActiveRecord::Migration + def self.up + add_index :queries, :project_id + add_index :queries, :user_id + end + + def self.down + remove_index :queries, :project_id + remove_index :queries, :user_id + end +end diff --git a/db/migrate/20091017214236_add_missing_indexes_to_time_entries.rb b/db/migrate/20091017214236_add_missing_indexes_to_time_entries.rb new file mode 100644 index 000000000..cffc528ea --- /dev/null +++ b/db/migrate/20091017214236_add_missing_indexes_to_time_entries.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToTimeEntries < ActiveRecord::Migration + def self.up + add_index :time_entries, :activity_id + add_index :time_entries, :user_id + end + + def self.down + remove_index :time_entries, :activity_id + remove_index :time_entries, :user_id + end +end diff --git a/db/migrate/20091017214308_add_missing_indexes_to_news.rb b/db/migrate/20091017214308_add_missing_indexes_to_news.rb new file mode 100644 index 000000000..808eb6294 --- /dev/null +++ b/db/migrate/20091017214308_add_missing_indexes_to_news.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToNews < ActiveRecord::Migration + def self.up + add_index :news, :author_id + end + + def self.down + remove_index :news, :author_id + end +end diff --git a/db/migrate/20091017214336_add_missing_indexes_to_users.rb b/db/migrate/20091017214336_add_missing_indexes_to_users.rb new file mode 100644 index 000000000..c5a509587 --- /dev/null +++ b/db/migrate/20091017214336_add_missing_indexes_to_users.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToUsers < ActiveRecord::Migration + def self.up + add_index :users, [:id, :type] + add_index :users, :auth_source_id + end + + def self.down + remove_index :users, :column => [:id, :type] + remove_index :users, :auth_source_id + end +end diff --git a/db/migrate/20091017214406_add_missing_indexes_to_attachments.rb b/db/migrate/20091017214406_add_missing_indexes_to_attachments.rb new file mode 100644 index 000000000..d22fc98ed --- /dev/null +++ b/db/migrate/20091017214406_add_missing_indexes_to_attachments.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToAttachments < ActiveRecord::Migration + def self.up + add_index :attachments, [:container_id, :container_type] + add_index :attachments, :author_id + end + + def self.down + remove_index :attachments, :column => [:container_id, :container_type] + remove_index :attachments, :author_id + end +end diff --git a/db/migrate/20091017214440_add_missing_indexes_to_wiki_contents.rb b/db/migrate/20091017214440_add_missing_indexes_to_wiki_contents.rb new file mode 100644 index 000000000..454e4c5d0 --- /dev/null +++ b/db/migrate/20091017214440_add_missing_indexes_to_wiki_contents.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToWikiContents < ActiveRecord::Migration + def self.up + add_index :wiki_contents, :author_id + end + + def self.down + remove_index :wiki_contents, :author_id + end +end diff --git a/db/migrate/20091017214519_add_missing_indexes_to_custom_values.rb b/db/migrate/20091017214519_add_missing_indexes_to_custom_values.rb new file mode 100644 index 000000000..b192a7e2a --- /dev/null +++ b/db/migrate/20091017214519_add_missing_indexes_to_custom_values.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToCustomValues < ActiveRecord::Migration + def self.up + add_index :custom_values, :custom_field_id + end + + def self.down + remove_index :custom_values, :custom_field_id + end +end diff --git a/db/migrate/20091017214611_add_missing_indexes_to_journals.rb b/db/migrate/20091017214611_add_missing_indexes_to_journals.rb new file mode 100644 index 000000000..2667f4034 --- /dev/null +++ b/db/migrate/20091017214611_add_missing_indexes_to_journals.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToJournals < ActiveRecord::Migration + def self.up + add_index :journals, :user_id + add_index :journals, :journalized_id + end + + def self.down + remove_index :journals, :user_id + remove_index :journals, :journalized_id + end +end diff --git a/db/migrate/20091017214644_add_missing_indexes_to_issue_relations.rb b/db/migrate/20091017214644_add_missing_indexes_to_issue_relations.rb new file mode 100644 index 000000000..fc57f18bf --- /dev/null +++ b/db/migrate/20091017214644_add_missing_indexes_to_issue_relations.rb @@ -0,0 +1,11 @@ +class AddMissingIndexesToIssueRelations < ActiveRecord::Migration + def self.up + add_index :issue_relations, :issue_from_id + add_index :issue_relations, :issue_to_id + end + + def self.down + remove_index :issue_relations, :issue_from_id + remove_index :issue_relations, :issue_to_id + end +end diff --git a/db/migrate/20091017214720_add_missing_indexes_to_wiki_redirects.rb b/db/migrate/20091017214720_add_missing_indexes_to_wiki_redirects.rb new file mode 100644 index 000000000..7442a544f --- /dev/null +++ b/db/migrate/20091017214720_add_missing_indexes_to_wiki_redirects.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToWikiRedirects < ActiveRecord::Migration + def self.up + add_index :wiki_redirects, :wiki_id + end + + def self.down + remove_index :wiki_redirects, :wiki_id + end +end diff --git a/db/migrate/20091017214750_add_missing_indexes_to_custom_fields_trackers.rb b/db/migrate/20091017214750_add_missing_indexes_to_custom_fields_trackers.rb new file mode 100644 index 000000000..c398b7931 --- /dev/null +++ b/db/migrate/20091017214750_add_missing_indexes_to_custom_fields_trackers.rb @@ -0,0 +1,9 @@ +class AddMissingIndexesToCustomFieldsTrackers < ActiveRecord::Migration + def self.up + add_index :custom_fields_trackers, [:custom_field_id, :tracker_id] + end + + def self.down + remove_index :custom_fields_trackers, :column => [:custom_field_id, :tracker_id] + end +end diff --git a/db/migrate/20091025163651_add_activity_indexes.rb b/db/migrate/20091025163651_add_activity_indexes.rb new file mode 100644 index 000000000..f18059316 --- /dev/null +++ b/db/migrate/20091025163651_add_activity_indexes.rb @@ -0,0 +1,25 @@ +class AddActivityIndexes < ActiveRecord::Migration + def self.up + add_index :journals, :created_on + add_index :changesets, :committed_on + add_index :wiki_content_versions, :updated_on + add_index :messages, :created_on + add_index :issues, :created_on + add_index :news, :created_on + add_index :attachments, :created_on + add_index :documents, :created_on + add_index :time_entries, :created_on + end + + def self.down + remove_index :journals, :created_on + remove_index :changesets, :committed_on + remove_index :wiki_content_versions, :updated_on + remove_index :messages, :created_on + remove_index :issues, :created_on + remove_index :news, :created_on + remove_index :attachments, :created_on + remove_index :documents, :created_on + remove_index :time_entries, :created_on + end +end diff --git a/db/migrate/20091108092559_add_versions_status.rb b/db/migrate/20091108092559_add_versions_status.rb new file mode 100644 index 000000000..99f5f5a0e --- /dev/null +++ b/db/migrate/20091108092559_add_versions_status.rb @@ -0,0 +1,10 @@ +class AddVersionsStatus < ActiveRecord::Migration + def self.up + add_column :versions, :status, :string, :default => 'open' + Version.update_all("status = 'open'") + end + + def self.down + remove_column :versions, :status + end +end diff --git a/db/migrate/20091114105931_add_view_issues_permission.rb b/db/migrate/20091114105931_add_view_issues_permission.rb new file mode 100644 index 000000000..d12b2deed --- /dev/null +++ b/db/migrate/20091114105931_add_view_issues_permission.rb @@ -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 --git a/db/migrate/20091123212029_add_default_done_ratio_to_issue_status.rb b/db/migrate/20091123212029_add_default_done_ratio_to_issue_status.rb new file mode 100644 index 000000000..0ce672100 --- /dev/null +++ b/db/migrate/20091123212029_add_default_done_ratio_to_issue_status.rb @@ -0,0 +1,9 @@ +class AddDefaultDoneRatioToIssueStatus < ActiveRecord::Migration + def self.up + add_column :issue_statuses, :default_done_ratio, :integer + end + + def self.down + remove_column :issue_statuses, :default_done_ratio + end +end diff --git a/db/migrate/20091205124427_add_versions_sharing.rb b/db/migrate/20091205124427_add_versions_sharing.rb new file mode 100644 index 000000000..3c28e1158 --- /dev/null +++ b/db/migrate/20091205124427_add_versions_sharing.rb @@ -0,0 +1,10 @@ +class AddVersionsSharing < ActiveRecord::Migration + def self.up + add_column :versions, :sharing, :string, :default => 'none', :null => false + add_index :versions, :sharing + end + + def self.down + remove_column :versions, :sharing + end +end diff --git a/db/migrate/20091220183509_add_lft_and_rgt_indexes_to_projects.rb b/db/migrate/20091220183509_add_lft_and_rgt_indexes_to_projects.rb new file mode 100644 index 000000000..1c0b4b313 --- /dev/null +++ b/db/migrate/20091220183509_add_lft_and_rgt_indexes_to_projects.rb @@ -0,0 +1,11 @@ +class AddLftAndRgtIndexesToProjects < ActiveRecord::Migration + def self.up + add_index :projects, :lft + add_index :projects, :rgt + end + + def self.down + remove_index :projects, :lft + remove_index :projects, :rgt + end +end diff --git a/db/migrate/20091220183727_add_index_to_settings_name.rb b/db/migrate/20091220183727_add_index_to_settings_name.rb new file mode 100644 index 000000000..e6c96ec3f --- /dev/null +++ b/db/migrate/20091220183727_add_index_to_settings_name.rb @@ -0,0 +1,9 @@ +class AddIndexToSettingsName < ActiveRecord::Migration + def self.up + add_index :settings, :name + end + + def self.down + remove_index :settings, :name + end +end diff --git a/db/migrate/20091220184736_add_indexes_to_issue_status.rb b/db/migrate/20091220184736_add_indexes_to_issue_status.rb new file mode 100644 index 000000000..2497a1e6a --- /dev/null +++ b/db/migrate/20091220184736_add_indexes_to_issue_status.rb @@ -0,0 +1,13 @@ +class AddIndexesToIssueStatus < ActiveRecord::Migration + def self.up + add_index :issue_statuses, :position + add_index :issue_statuses, :is_closed + add_index :issue_statuses, :is_default + end + + def self.down + remove_index :issue_statuses, :position + remove_index :issue_statuses, :is_closed + remove_index :issue_statuses, :is_default + end +end diff --git a/db/migrate/20091225164732_remove_enumerations_opt.rb b/db/migrate/20091225164732_remove_enumerations_opt.rb new file mode 100644 index 000000000..72c39e05b --- /dev/null +++ b/db/migrate/20091225164732_remove_enumerations_opt.rb @@ -0,0 +1,12 @@ +class RemoveEnumerationsOpt < ActiveRecord::Migration + def self.up + remove_column :enumerations, :opt + end + + def self.down + add_column :enumerations, :opt, :string, :limit => 4, :default => '', :null => false + Enumeration.update_all("opt = 'IPRI'", "type = 'IssuePriority'") + Enumeration.update_all("opt = 'DCAT'", "type = 'DocumentCategory'") + Enumeration.update_all("opt = 'ACTI'", "type = 'TimeEntryActivity'") + end +end diff --git a/db/migrate/20091227112908_change_wiki_contents_text_limit.rb b/db/migrate/20091227112908_change_wiki_contents_text_limit.rb new file mode 100644 index 000000000..225f71e68 --- /dev/null +++ b/db/migrate/20091227112908_change_wiki_contents_text_limit.rb @@ -0,0 +1,16 @@ +class ChangeWikiContentsTextLimit < ActiveRecord::Migration + def self.up + # Migrates MySQL databases only + # Postgres would raise an error (see http://dev.rubyonrails.org/ticket/3818) + # Not fixed in Rails 2.3.5 + if ActiveRecord::Base.connection.adapter_name =~ /mysql/i + max_size = 16.megabytes + change_column :wiki_contents, :text, :text, :limit => max_size + change_column :wiki_content_versions, :data, :binary, :limit => max_size + end + end + + def self.down + # no-op + end +end diff --git a/db/migrate/20100129193402_change_users_mail_notification_to_string.rb b/db/migrate/20100129193402_change_users_mail_notification_to_string.rb new file mode 100644 index 000000000..401f63407 --- /dev/null +++ b/db/migrate/20100129193402_change_users_mail_notification_to_string.rb @@ -0,0 +1,17 @@ +class ChangeUsersMailNotificationToString < ActiveRecord::Migration + def self.up + rename_column :users, :mail_notification, :mail_notification_bool + add_column :users, :mail_notification, :string, :default => '', :null => false + User.update_all("mail_notification = 'all'", "mail_notification_bool = #{connection.quoted_true}") + User.update_all("mail_notification = 'selected'", "EXISTS (SELECT 1 FROM #{Member.table_name} WHERE #{Member.table_name}.mail_notification = #{connection.quoted_true} AND #{Member.table_name}.user_id = #{User.table_name}.id)") + User.update_all("mail_notification = 'only_my_events'", "mail_notification NOT IN ('all', 'selected')") + remove_column :users, :mail_notification_bool + end + + def self.down + rename_column :users, :mail_notification, :mail_notification_char + add_column :users, :mail_notification, :boolean, :default => true, :null => false + User.update_all("mail_notification = #{connection.quoted_false}", "mail_notification_char <> 'all'") + remove_column :users, :mail_notification_char + end +end diff --git a/db/migrate/20100129193813_update_mail_notification_values.rb b/db/migrate/20100129193813_update_mail_notification_values.rb new file mode 100644 index 000000000..a8a45ade3 --- /dev/null +++ b/db/migrate/20100129193813_update_mail_notification_values.rb @@ -0,0 +1,11 @@ +# Patch the data from a boolean change. +class UpdateMailNotificationValues < ActiveRecord::Migration + def self.up + # No-op + # See 20100129193402_change_users_mail_notification_to_string.rb + end + + def self.down + # No-op + end +end diff --git a/db/migrate/20100221100219_add_index_on_changesets_scmid.rb b/db/migrate/20100221100219_add_index_on_changesets_scmid.rb new file mode 100644 index 000000000..96d85a3a7 --- /dev/null +++ b/db/migrate/20100221100219_add_index_on_changesets_scmid.rb @@ -0,0 +1,9 @@ +class AddIndexOnChangesetsScmid < ActiveRecord::Migration + def self.up + add_index :changesets, [:repository_id, :scmid], :name => :changesets_repos_scmid + end + + def self.down + remove_index :changesets, :name => :changesets_repos_scmid + end +end diff --git a/db/migrate/20100313132032_add_issues_nested_sets_columns.rb b/db/migrate/20100313132032_add_issues_nested_sets_columns.rb new file mode 100644 index 000000000..2467f6f67 --- /dev/null +++ b/db/migrate/20100313132032_add_issues_nested_sets_columns.rb @@ -0,0 +1,17 @@ +class AddIssuesNestedSetsColumns < ActiveRecord::Migration + def self.up + add_column :issues, :parent_id, :integer, :default => nil + add_column :issues, :root_id, :integer, :default => nil + add_column :issues, :lft, :integer, :default => nil + add_column :issues, :rgt, :integer, :default => nil + + Issue.update_all("parent_id = NULL, root_id = id, lft = 1, rgt = 2") + end + + def self.down + remove_column :issues, :parent_id + remove_column :issues, :root_id + remove_column :issues, :lft + remove_column :issues, :rgt + end +end diff --git a/db/migrate/20100313171051_add_index_on_issues_nested_set.rb b/db/migrate/20100313171051_add_index_on_issues_nested_set.rb new file mode 100644 index 000000000..4dc948000 --- /dev/null +++ b/db/migrate/20100313171051_add_index_on_issues_nested_set.rb @@ -0,0 +1,9 @@ +class AddIndexOnIssuesNestedSet < ActiveRecord::Migration + def self.up + add_index :issues, [:root_id, :lft, :rgt] + end + + def self.down + remove_index :issues, [:root_id, :lft, :rgt] + end +end diff --git a/db/migrate/20100705164950_change_changes_path_length_limit.rb b/db/migrate/20100705164950_change_changes_path_length_limit.rb new file mode 100644 index 000000000..e00b69d08 --- /dev/null +++ b/db/migrate/20100705164950_change_changes_path_length_limit.rb @@ -0,0 +1,14 @@ +class ChangeChangesPathLengthLimit < ActiveRecord::Migration + def self.up + # these are two steps to please MySQL 5 on Win32 + change_column :changes, :path, :text, :default => nil, :null => true + change_column :changes, :path, :text, :null => false + + change_column :changes, :from_path, :text + end + + def self.down + change_column :changes, :path, :string, :default => "", :null => false + change_column :changes, :from_path, :string + end +end diff --git a/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb b/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb new file mode 100644 index 000000000..59cd40049 --- /dev/null +++ b/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb @@ -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 --git a/db/migrate/20101104182107_add_unique_index_on_members.rb b/db/migrate/20101104182107_add_unique_index_on_members.rb new file mode 100644 index 000000000..14d1585f7 --- /dev/null +++ b/db/migrate/20101104182107_add_unique_index_on_members.rb @@ -0,0 +1,22 @@ +class AddUniqueIndexOnMembers < ActiveRecord::Migration + def self.up + # Clean and reassign MemberRole rows if needed + MemberRole.delete_all("member_id NOT IN (SELECT id FROM #{Member.table_name})") + MemberRole.update_all("member_id =" + + " (SELECT min(m2.id) FROM #{Member.table_name} m1, #{Member.table_name} m2" + + " WHERE m1.user_id = m2.user_id AND m1.project_id = m2.project_id" + + " AND m1.id = #{MemberRole.table_name}.member_id)") + # Remove duplicates + Member.connection.select_values("SELECT m.id FROM #{Member.table_name} m" + + " WHERE m.id > (SELECT min(m1.id) FROM #{Member.table_name} m1 WHERE m1.user_id = m.user_id AND m1.project_id = m.project_id)").each do |i| + Member.delete_all(["id = ?", i]) + end + + # Then add a unique index + add_index :members, [:user_id, :project_id], :unique => true + end + + def self.down + remove_index :members, [:user_id, :project_id] + end +end diff --git a/db/migrate/20101107130441_add_custom_fields_visible.rb b/db/migrate/20101107130441_add_custom_fields_visible.rb new file mode 100644 index 000000000..9d59faee5 --- /dev/null +++ b/db/migrate/20101107130441_add_custom_fields_visible.rb @@ -0,0 +1,10 @@ +class AddCustomFieldsVisible < ActiveRecord::Migration + def self.up + add_column :custom_fields, :visible, :boolean, :null => false, :default => true + CustomField.update_all("visible = #{CustomField.connection.quoted_true}") + end + + def self.down + remove_column :custom_fields, :visible + end +end diff --git a/db/migrate/20101114115114_change_projects_name_limit.rb b/db/migrate/20101114115114_change_projects_name_limit.rb new file mode 100644 index 000000000..fabc3c9d8 --- /dev/null +++ b/db/migrate/20101114115114_change_projects_name_limit.rb @@ -0,0 +1,9 @@ +class ChangeProjectsNameLimit < ActiveRecord::Migration + def self.up + change_column :projects, :name, :string, :limit => nil, :default => '', :null => false + end + + def self.down + change_column :projects, :name, :string, :limit => 30, :default => '', :null => false + end +end diff --git a/db/migrate/20101114115359_change_projects_identifier_limit.rb b/db/migrate/20101114115359_change_projects_identifier_limit.rb new file mode 100644 index 000000000..79426fadf --- /dev/null +++ b/db/migrate/20101114115359_change_projects_identifier_limit.rb @@ -0,0 +1,9 @@ +class ChangeProjectsIdentifierLimit < ActiveRecord::Migration + def self.up + change_column :projects, :identifier, :string, :limit => nil + end + + def self.down + change_column :projects, :identifier, :string, :limit => 20 + end +end diff --git a/db/migrate/20110220160626_add_workflows_assignee_and_author.rb b/db/migrate/20110220160626_add_workflows_assignee_and_author.rb new file mode 100644 index 000000000..448ac6302 --- /dev/null +++ b/db/migrate/20110220160626_add_workflows_assignee_and_author.rb @@ -0,0 +1,14 @@ +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 + + WorkflowRule.update_all(:assignee => false) + WorkflowRule.update_all(:author => false) + end + + def self.down + remove_column :workflows, :assignee + remove_column :workflows, :author + end +end diff --git a/db/migrate/20110223180944_add_users_salt.rb b/db/migrate/20110223180944_add_users_salt.rb new file mode 100644 index 000000000..f1cf6483f --- /dev/null +++ b/db/migrate/20110223180944_add_users_salt.rb @@ -0,0 +1,9 @@ +class AddUsersSalt < ActiveRecord::Migration + def self.up + add_column :users, :salt, :string, :limit => 64 + end + + def self.down + remove_column :users, :salt + end +end diff --git a/db/migrate/20110223180953_salt_user_passwords.rb b/db/migrate/20110223180953_salt_user_passwords.rb new file mode 100644 index 000000000..9f017db9c --- /dev/null +++ b/db/migrate/20110223180953_salt_user_passwords.rb @@ -0,0 +1,13 @@ +class SaltUserPasswords < ActiveRecord::Migration + + def self.up + say_with_time "Salting user passwords, this may take some time..." do + User.salt_unsalted_passwords! + end + end + + def self.down + # Unsalted passwords can not be restored + raise ActiveRecord::IrreversibleMigration, "Can't decypher salted passwords. This migration can not be rollback'ed." + end +end diff --git a/db/migrate/20110224000000_add_repositories_path_encoding.rb b/db/migrate/20110224000000_add_repositories_path_encoding.rb new file mode 100644 index 000000000..253d7a66e --- /dev/null +++ b/db/migrate/20110224000000_add_repositories_path_encoding.rb @@ -0,0 +1,9 @@ +class AddRepositoriesPathEncoding < ActiveRecord::Migration + def self.up + add_column :repositories, :path_encoding, :string, :limit => 64, :default => nil + end + + def self.down + remove_column :repositories, :path_encoding + end +end diff --git a/db/migrate/20110226120112_change_repositories_password_limit.rb b/db/migrate/20110226120112_change_repositories_password_limit.rb new file mode 100644 index 000000000..1ad937c7d --- /dev/null +++ b/db/migrate/20110226120112_change_repositories_password_limit.rb @@ -0,0 +1,9 @@ +class ChangeRepositoriesPasswordLimit < ActiveRecord::Migration + def self.up + change_column :repositories, :password, :string, :limit => nil, :default => '' + end + + def self.down + change_column :repositories, :password, :string, :limit => 60, :default => '' + end +end diff --git a/db/migrate/20110226120132_change_auth_sources_account_password_limit.rb b/db/migrate/20110226120132_change_auth_sources_account_password_limit.rb new file mode 100644 index 000000000..b1cd80aa5 --- /dev/null +++ b/db/migrate/20110226120132_change_auth_sources_account_password_limit.rb @@ -0,0 +1,9 @@ +class ChangeAuthSourcesAccountPasswordLimit < ActiveRecord::Migration + def self.up + change_column :auth_sources, :account_password, :string, :limit => nil, :default => '' + end + + def self.down + change_column :auth_sources, :account_password, :string, :limit => 60, :default => '' + end +end diff --git a/db/migrate/20110227125750_change_journal_details_values_to_text.rb b/db/migrate/20110227125750_change_journal_details_values_to_text.rb new file mode 100644 index 000000000..25886575c --- /dev/null +++ b/db/migrate/20110227125750_change_journal_details_values_to_text.rb @@ -0,0 +1,11 @@ +class ChangeJournalDetailsValuesToText < ActiveRecord::Migration + def self.up + change_column :journal_details, :old_value, :text + change_column :journal_details, :value, :text + end + + def self.down + change_column :journal_details, :old_value, :string + change_column :journal_details, :value, :string + end +end diff --git a/db/migrate/20110228000000_add_repositories_log_encoding.rb b/db/migrate/20110228000000_add_repositories_log_encoding.rb new file mode 100644 index 000000000..85cadafce --- /dev/null +++ b/db/migrate/20110228000000_add_repositories_log_encoding.rb @@ -0,0 +1,9 @@ +class AddRepositoriesLogEncoding < ActiveRecord::Migration + def self.up + add_column :repositories, :log_encoding, :string, :limit => 64, :default => nil + end + + def self.down + remove_column :repositories, :log_encoding + end +end diff --git a/db/migrate/20110228000100_copy_repositories_log_encoding.rb b/db/migrate/20110228000100_copy_repositories_log_encoding.rb new file mode 100644 index 000000000..314932883 --- /dev/null +++ b/db/migrate/20110228000100_copy_repositories_log_encoding.rb @@ -0,0 +1,11 @@ +class CopyRepositoriesLogEncoding < ActiveRecord::Migration + def self.up + encoding = Setting.commit_logs_encoding.to_s.strip + encoding = encoding.blank? ? 'UTF-8' : encoding + # encoding is NULL by default + Repository.update_all(["log_encoding = ?", encoding], "type IN ('Bazaar', 'Cvs', 'Darcs')") + end + + def self.down + end +end diff --git a/db/migrate/20110401192910_add_index_to_users_type.rb b/db/migrate/20110401192910_add_index_to_users_type.rb new file mode 100644 index 000000000..b9f501120 --- /dev/null +++ b/db/migrate/20110401192910_add_index_to_users_type.rb @@ -0,0 +1,9 @@ +class AddIndexToUsersType < ActiveRecord::Migration + def self.up + add_index :users, :type + end + + def self.down + remove_index :users, :type + end +end diff --git a/db/migrate/20110408103312_add_roles_issues_visibility.rb b/db/migrate/20110408103312_add_roles_issues_visibility.rb new file mode 100644 index 000000000..1e6b29a64 --- /dev/null +++ b/db/migrate/20110408103312_add_roles_issues_visibility.rb @@ -0,0 +1,9 @@ +class AddRolesIssuesVisibility < ActiveRecord::Migration + def self.up + add_column :roles, :issues_visibility, :string, :limit => 30, :default => 'default', :null => false + end + + def self.down + remove_column :roles, :issues_visibility + end +end diff --git a/db/migrate/20110412065600_add_issues_is_private.rb b/db/migrate/20110412065600_add_issues_is_private.rb new file mode 100644 index 000000000..2cc4e4b15 --- /dev/null +++ b/db/migrate/20110412065600_add_issues_is_private.rb @@ -0,0 +1,9 @@ +class AddIssuesIsPrivate < ActiveRecord::Migration + def self.up + add_column :issues, :is_private, :boolean, :default => false, :null => false + end + + def self.down + remove_column :issues, :is_private + end +end diff --git a/db/migrate/20110511000000_add_repositories_extra_info.rb b/db/migrate/20110511000000_add_repositories_extra_info.rb new file mode 100644 index 000000000..a5280dc57 --- /dev/null +++ b/db/migrate/20110511000000_add_repositories_extra_info.rb @@ -0,0 +1,9 @@ +class AddRepositoriesExtraInfo < ActiveRecord::Migration + def self.up + add_column :repositories, :extra_info, :text + end + + def self.down + remove_column :repositories, :extra_info + end +end diff --git a/db/migrate/20110902000000_create_changeset_parents.rb b/db/migrate/20110902000000_create_changeset_parents.rb new file mode 100644 index 000000000..e679d3f91 --- /dev/null +++ b/db/migrate/20110902000000_create_changeset_parents.rb @@ -0,0 +1,14 @@ +class CreateChangesetParents < ActiveRecord::Migration + def self.up + create_table :changeset_parents, :id => false do |t| + t.column :changeset_id, :integer, :null => false + t.column :parent_id, :integer, :null => false + end + add_index :changeset_parents, [:changeset_id], :unique => false, :name => :changeset_parents_changeset_ids + add_index :changeset_parents, [:parent_id], :unique => false, :name => :changeset_parents_parent_ids + end + + def self.down + drop_table :changeset_parents + end +end diff --git a/db/migrate/20111201201315_add_unique_index_to_issue_relations.rb b/db/migrate/20111201201315_add_unique_index_to_issue_relations.rb new file mode 100644 index 000000000..c27158c13 --- /dev/null +++ b/db/migrate/20111201201315_add_unique_index_to_issue_relations.rb @@ -0,0 +1,16 @@ +class AddUniqueIndexToIssueRelations < ActiveRecord::Migration + def self.up + + # Remove duplicates + IssueRelation.connection.select_values("SELECT r.id FROM #{IssueRelation.table_name} r" + + " WHERE r.id > (SELECT min(r1.id) FROM #{IssueRelation.table_name} r1 WHERE r1.issue_from_id = r.issue_from_id AND r1.issue_to_id = r.issue_to_id)").each do |i| + IssueRelation.delete_all(["id = ?", i]) + end + + add_index :issue_relations, [:issue_from_id, :issue_to_id], :unique => true + end + + def self.down + remove_index :issue_relations, :column => [:issue_from_id, :issue_to_id] + end +end diff --git a/db/migrate/20120115143024_add_repositories_identifier.rb b/db/migrate/20120115143024_add_repositories_identifier.rb new file mode 100644 index 000000000..b54ebd1d5 --- /dev/null +++ b/db/migrate/20120115143024_add_repositories_identifier.rb @@ -0,0 +1,9 @@ +class AddRepositoriesIdentifier < ActiveRecord::Migration + def self.up + add_column :repositories, :identifier, :string + end + + def self.down + remove_column :repositories, :identifier + end +end diff --git a/db/migrate/20120115143100_add_repositories_is_default.rb b/db/migrate/20120115143100_add_repositories_is_default.rb new file mode 100644 index 000000000..87f018120 --- /dev/null +++ b/db/migrate/20120115143100_add_repositories_is_default.rb @@ -0,0 +1,9 @@ +class AddRepositoriesIsDefault < ActiveRecord::Migration + def self.up + add_column :repositories, :is_default, :boolean, :default => false + end + + def self.down + remove_column :repositories, :is_default + end +end diff --git a/db/migrate/20120115143126_set_default_repositories.rb b/db/migrate/20120115143126_set_default_repositories.rb new file mode 100644 index 000000000..cd7674e71 --- /dev/null +++ b/db/migrate/20120115143126_set_default_repositories.rb @@ -0,0 +1,14 @@ +class SetDefaultRepositories < ActiveRecord::Migration + def self.up + Repository.update_all(["is_default = ?", false]) + # Sets the last repository as default in case multiple repositories exist for the same project + Repository.connection.select_values("SELECT r.id FROM #{Repository.table_name} r" + + " WHERE r.id = (SELECT max(r1.id) FROM #{Repository.table_name} r1 WHERE r1.project_id = r.project_id)").each do |i| + Repository.update_all(["is_default = ?", true], ["id = ?", i]) + end + end + + def self.down + Repository.update_all(["is_default = ?", false]) + end +end diff --git a/db/migrate/20120127174243_add_custom_fields_multiple.rb b/db/migrate/20120127174243_add_custom_fields_multiple.rb new file mode 100644 index 000000000..caee40bd4 --- /dev/null +++ b/db/migrate/20120127174243_add_custom_fields_multiple.rb @@ -0,0 +1,9 @@ +class AddCustomFieldsMultiple < ActiveRecord::Migration + def self.up + add_column :custom_fields, :multiple, :boolean, :default => false + end + + def self.down + remove_column :custom_fields, :multiple + end +end diff --git a/db/migrate/20120205111326_change_users_login_limit.rb b/db/migrate/20120205111326_change_users_login_limit.rb new file mode 100644 index 000000000..4508a5c40 --- /dev/null +++ b/db/migrate/20120205111326_change_users_login_limit.rb @@ -0,0 +1,9 @@ +class ChangeUsersLoginLimit < ActiveRecord::Migration + def self.up + change_column :users, :login, :string, :limit => nil, :default => '', :null => false + end + + def self.down + change_column :users, :login, :string, :limit => 30, :default => '', :null => false + end +end diff --git a/db/migrate/20120223110929_change_attachments_container_defaults.rb b/db/migrate/20120223110929_change_attachments_container_defaults.rb new file mode 100644 index 000000000..f959f4c33 --- /dev/null +++ b/db/migrate/20120223110929_change_attachments_container_defaults.rb @@ -0,0 +1,25 @@ +class ChangeAttachmentsContainerDefaults < ActiveRecord::Migration + def self.up + # Need to drop the index otherwise the following error occurs in Rails 3.1.3: + # + # Index name 'temp_index_altered_attachments_on_container_id_and_container_type' on + # table 'altered_attachments' is too long; the limit is 64 characters + remove_index :attachments, [:container_id, :container_type] + + change_column :attachments, :container_id, :integer, :default => nil, :null => true + change_column :attachments, :container_type, :string, :limit => 30, :default => nil, :null => true + Attachment.update_all "container_id = NULL", "container_id = 0" + Attachment.update_all "container_type = NULL", "container_type = ''" + + add_index :attachments, [:container_id, :container_type] + end + + def self.down + remove_index :attachments, [:container_id, :container_type] + + change_column :attachments, :container_id, :integer, :default => 0, :null => false + change_column :attachments, :container_type, :string, :limit => 30, :default => "", :null => false + + add_index :attachments, [:container_id, :container_type] + end +end diff --git a/db/migrate/20120301153455_add_auth_sources_filter.rb b/db/migrate/20120301153455_add_auth_sources_filter.rb new file mode 100644 index 000000000..617b3b77e --- /dev/null +++ b/db/migrate/20120301153455_add_auth_sources_filter.rb @@ -0,0 +1,9 @@ +class AddAuthSourcesFilter < ActiveRecord::Migration + def self.up + add_column :auth_sources, :filter, :string + end + + def self.down + remove_column :auth_sources, :filter + end +end diff --git a/db/migrate/20120422150750_change_repositories_to_full_sti.rb b/db/migrate/20120422150750_change_repositories_to_full_sti.rb new file mode 100644 index 000000000..067d60256 --- /dev/null +++ b/db/migrate/20120422150750_change_repositories_to_full_sti.rb @@ -0,0 +1,17 @@ +class ChangeRepositoriesToFullSti < ActiveRecord::Migration + def up + Repository.connection.select_rows("SELECT id, type FROM #{Repository.table_name}").each do |repository_id, repository_type| + unless repository_type =~ /^Repository::/ + Repository.update_all ["type = ?", "Repository::#{repository_type}"], ["id = ?", repository_id] + end + end + end + + def down + Repository.connection.select_rows("SELECT id, type FROM #{Repository.table_name}").each do |repository_id, repository_type| + if repository_type =~ /^Repository::(.+)$/ + Repository.update_all ["type = ?", $1], ["id = ?", repository_id] + end + end + end +end diff --git a/db/migrate/20120705074331_add_trackers_fields_bits.rb b/db/migrate/20120705074331_add_trackers_fields_bits.rb new file mode 100644 index 000000000..5d8458382 --- /dev/null +++ b/db/migrate/20120705074331_add_trackers_fields_bits.rb @@ -0,0 +1,9 @@ +class AddTrackersFieldsBits < ActiveRecord::Migration + def self.up + add_column :trackers, :fields_bits, :integer, :default => 0 + end + + def self.down + remove_column :trackers, :fields_bits + end +end diff --git a/db/migrate/20120707064544_add_auth_sources_timeout.rb b/db/migrate/20120707064544_add_auth_sources_timeout.rb new file mode 100644 index 000000000..40f467810 --- /dev/null +++ b/db/migrate/20120707064544_add_auth_sources_timeout.rb @@ -0,0 +1,9 @@ +class AddAuthSourcesTimeout < ActiveRecord::Migration + def up + add_column :auth_sources, :timeout, :integer + end + + def self.down + remove_column :auth_sources, :timeout + end +end diff --git a/db/migrate/20120714122000_add_workflows_type.rb b/db/migrate/20120714122000_add_workflows_type.rb new file mode 100644 index 000000000..f263f25df --- /dev/null +++ b/db/migrate/20120714122000_add_workflows_type.rb @@ -0,0 +1,9 @@ +class AddWorkflowsType < ActiveRecord::Migration + def up + add_column :workflows, :type, :string, :limit => 30 + end + + def down + remove_column :workflows, :type + end +end diff --git a/db/migrate/20120714122100_update_workflows_to_sti.rb b/db/migrate/20120714122100_update_workflows_to_sti.rb new file mode 100644 index 000000000..8ee5c6dc3 --- /dev/null +++ b/db/migrate/20120714122100_update_workflows_to_sti.rb @@ -0,0 +1,9 @@ +class UpdateWorkflowsToSti < ActiveRecord::Migration + def up + WorkflowRule.update_all "type = 'WorkflowTransition'" + end + + def down + WorkflowRule.update_all "type = NULL" + end +end diff --git a/db/migrate/20120714122200_add_workflows_rule_fields.rb b/db/migrate/20120714122200_add_workflows_rule_fields.rb new file mode 100644 index 000000000..6e9c7df70 --- /dev/null +++ b/db/migrate/20120714122200_add_workflows_rule_fields.rb @@ -0,0 +1,11 @@ +class AddWorkflowsRuleFields < ActiveRecord::Migration + def up + add_column :workflows, :field_name, :string, :limit => 30 + add_column :workflows, :rule, :string, :limit => 30 + end + + def down + remove_column :workflows, :field_name + remove_column :workflows, :rule + end +end diff --git a/db/migrate/20120731164049_add_boards_parent_id.rb b/db/migrate/20120731164049_add_boards_parent_id.rb new file mode 100644 index 000000000..c9ce47f78 --- /dev/null +++ b/db/migrate/20120731164049_add_boards_parent_id.rb @@ -0,0 +1,9 @@ +class AddBoardsParentId < ActiveRecord::Migration + def up + add_column :boards, :parent_id, :integer + end + + def down + remove_column :boards, :parent_id + end +end diff --git a/db/migrate/20120930112914_add_journals_private_notes.rb b/db/migrate/20120930112914_add_journals_private_notes.rb new file mode 100644 index 000000000..41eb0e9ef --- /dev/null +++ b/db/migrate/20120930112914_add_journals_private_notes.rb @@ -0,0 +1,9 @@ +class AddJournalsPrivateNotes < ActiveRecord::Migration + def up + add_column :journals, :private_notes, :boolean, :default => false, :null => false + end + + def down + remove_column :journals, :private_notes + end +end diff --git a/db/migrate/20121026002032_add_enumerations_position_name.rb b/db/migrate/20121026002032_add_enumerations_position_name.rb new file mode 100644 index 000000000..52cbe08eb --- /dev/null +++ b/db/migrate/20121026002032_add_enumerations_position_name.rb @@ -0,0 +1,9 @@ +class AddEnumerationsPositionName < ActiveRecord::Migration + def up + add_column :enumerations, :position_name, :string, :limit => 30 + end + + def down + remove_column :enumerations, :position_name + end +end diff --git a/db/migrate/20121026003537_populate_enumerations_position_name.rb b/db/migrate/20121026003537_populate_enumerations_position_name.rb new file mode 100644 index 000000000..31777b75f --- /dev/null +++ b/db/migrate/20121026003537_populate_enumerations_position_name.rb @@ -0,0 +1,9 @@ +class PopulateEnumerationsPositionName < ActiveRecord::Migration + def up + IssuePriority.compute_position_names + end + + def down + IssuePriority.clear_position_names + end +end diff --git a/db/migrate/20121209123234_add_queries_type.rb b/db/migrate/20121209123234_add_queries_type.rb new file mode 100644 index 000000000..202d524e1 --- /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 --git a/db/migrate/20121209123358_update_queries_to_sti.rb b/db/migrate/20121209123358_update_queries_to_sti.rb new file mode 100644 index 000000000..d8dea4070 --- /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 --git a/db/migrate/20121213084931_add_attachments_disk_directory.rb b/db/migrate/20121213084931_add_attachments_disk_directory.rb new file mode 100644 index 000000000..d11fcad9b --- /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 --git a/db/migrate/20130110122628_split_documents_permissions.rb b/db/migrate/20130110122628_split_documents_permissions.rb new file mode 100644 index 000000000..0e010aa5c --- /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 --git a/db/migrate/20130201184705_add_unique_index_on_tokens_value.rb b/db/migrate/20130201184705_add_unique_index_on_tokens_value.rb new file mode 100644 index 000000000..fdec9f8ee --- /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 --git a/db/migrate/20130202090625_add_projects_inherit_members.rb b/db/migrate/20130202090625_add_projects_inherit_members.rb new file mode 100644 index 000000000..9cf5bade3 --- /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 --git a/db/migrate/20130207175206_add_unique_index_on_custom_fields_trackers.rb b/db/migrate/20130207175206_add_unique_index_on_custom_fields_trackers.rb new file mode 100644 index 000000000..9977dcd50 --- /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 --git a/db/migrate/20130207181455_add_unique_index_on_custom_fields_projects.rb b/db/migrate/20130207181455_add_unique_index_on_custom_fields_projects.rb new file mode 100644 index 000000000..223818d4f --- /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 --git a/db/migrate/20130215073721_change_users_lastname_length_to_255.rb b/db/migrate/20130215073721_change_users_lastname_length_to_255.rb new file mode 100644 index 000000000..7d68e37d8 --- /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 --git a/db/migrate/20130215111127_add_issues_closed_on.rb b/db/migrate/20130215111127_add_issues_closed_on.rb new file mode 100644 index 000000000..2670deba5 --- /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 --git a/db/migrate/20130215111141_populate_issues_closed_on.rb b/db/migrate/20130215111141_populate_issues_closed_on.rb new file mode 100644 index 000000000..b2a828be4 --- /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 --git a/db/migrate/20130217094251_remove_issues_default_fk_values.rb b/db/migrate/20130217094251_remove_issues_default_fk_values.rb new file mode 100644 index 000000000..9345cf0b8 --- /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 --git a/db/migrate/20130725021433_acts_as_taggable_on_migration.rb b/db/migrate/20130725021433_acts_as_taggable_on_migration.rb new file mode 100644 index 000000000..e8b978d96 --- /dev/null +++ b/db/migrate/20130725021433_acts_as_taggable_on_migration.rb @@ -0,0 +1,30 @@ +class ActsAsTaggableOnMigration < ActiveRecord::Migration + def self.up + create_table :tags do |t| + t.string :name + end + + create_table :taggings do |t| + t.references :tag + + # You should make sure that the column created is + # long enough to store the required class names. + t.references :taggable, :polymorphic => true + t.references :tagger, :polymorphic => true + + # Limit is created to prevent MySQL error on index + # length for MyISAM table type: http://bit.ly/vgW2Ql + t.string :context, :limit => 128 + + t.datetime :created_at + end + + add_index :taggings, :tag_id + add_index :taggings, [:taggable_id, :taggable_type, :context] + end + + def self.down + drop_table :taggings + drop_table :tags + end +end diff --git a/db/migrate/20130725122407_create_bids.rb b/db/migrate/20130725122407_create_bids.rb new file mode 100644 index 000000000..7297712df --- /dev/null +++ b/db/migrate/20130725122407_create_bids.rb @@ -0,0 +1,13 @@ +class CreateBids < ActiveRecord::Migration + def change + create_table :bids do |t| + t.string :name + t.integer :budget + t.integer :author_id + t.date :deadline + t.string :description + + t.timestamps + end + end +end diff --git a/db/migrate/20130725132508_create_biding_projects.rb b/db/migrate/20130725132508_create_biding_projects.rb new file mode 100644 index 000000000..9eaf7bdec --- /dev/null +++ b/db/migrate/20130725132508_create_biding_projects.rb @@ -0,0 +1,12 @@ +class CreateBidingProjects < ActiveRecord::Migration + def change + create_table :biding_projects do |t| + t.integer :project_id + t.integer :bid_id + t.integer :user_id + t.string :description + + t.timestamps + end + end +end diff --git a/db/migrate/20130727021306_create_journals_for_messages.rb b/db/migrate/20130727021306_create_journals_for_messages.rb new file mode 100644 index 000000000..cd19ed9f1 --- /dev/null +++ b/db/migrate/20130727021306_create_journals_for_messages.rb @@ -0,0 +1,14 @@ +class CreateJournalsForMessages < ActiveRecord::Migration + def change + create_table :journals_for_messages do |t| + t.integer :jour_id + t.string :jour_type + t.integer :user_id + t.text :notes + t.integer :status + t.integer :reply_id + + t.timestamps + end + end +end diff --git a/db/migrate/20130728021709_add_commit_to_bids.rb b/db/migrate/20130728021709_add_commit_to_bids.rb new file mode 100644 index 000000000..dc0cd93f3 --- /dev/null +++ b/db/migrate/20130728021709_add_commit_to_bids.rb @@ -0,0 +1,5 @@ +class AddCommitToBids < ActiveRecord::Migration + def change + add_column :bids, :commit, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..a6de651e1 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,741 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20130729033444) do + + create_table "a_user_watchers", :force => true do |t| + t.string "name" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "member_id" + end + + create_table "attachments", :force => true do |t| + t.integer "container_id" + t.string "container_type", :limit => 30 + t.string "filename", :default => "", :null => false + t.string "disk_filename", :default => "", :null => false + t.integer "filesize", :default => 0, :null => false + t.string "content_type", :default => "" + t.string "digest", :limit => 40, :default => "", :null => false + t.integer "downloads", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.string "description" + t.string "disk_directory" + end + + add_index "attachments", ["author_id"], :name => "index_attachments_on_author_id" + add_index "attachments", ["container_id", "container_type"], :name => "index_attachments_on_container_id_and_container_type" + add_index "attachments", ["created_on"], :name => "index_attachments_on_created_on" + + create_table "auth_sources", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 60, :default => "", :null => false + t.string "host", :limit => 60 + t.integer "port" + t.string "account" + t.string "account_password", :default => "" + t.string "base_dn" + t.string "attr_login", :limit => 30 + t.string "attr_firstname", :limit => 30 + t.string "attr_lastname", :limit => 30 + t.string "attr_mail", :limit => 30 + t.boolean "onthefly_register", :default => false, :null => false + t.boolean "tls", :default => false, :null => false + t.string "filter" + t.integer "timeout" + end + + add_index "auth_sources", ["id", "type"], :name => "index_auth_sources_on_id_and_type" + + create_table "b_watcher_lists", :force => true do |t| + t.string "name" + t.integer "user_id" + t.string "sexual" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "biding_projects", :force => true do |t| + t.integer "project_id" + t.integer "bid_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "bids", :force => true do |t| + t.string "name" + t.integer "budget" + t.integer "author_id" + t.date "deadline" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "commit" + end + + create_table "boards", :force => true do |t| + t.integer "project_id", :null => false + t.string "name", :default => "", :null => false + t.string "description" + t.integer "position", :default => 1 + t.integer "topics_count", :default => 0, :null => false + t.integer "messages_count", :default => 0, :null => false + t.integer "last_message_id" + t.integer "parent_id" + end + + add_index "boards", ["last_message_id"], :name => "index_boards_on_last_message_id" + add_index "boards", ["project_id"], :name => "boards_project_id" + + create_table "changes", :force => true do |t| + t.integer "changeset_id", :null => false + t.string "action", :limit => 1, :default => "", :null => false + t.text "path", :null => false + t.text "from_path" + t.string "from_revision" + t.string "revision" + t.string "branch" + end + + add_index "changes", ["changeset_id"], :name => "changesets_changeset_id" + + create_table "changeset_parents", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "parent_id", :null => false + end + + add_index "changeset_parents", ["changeset_id"], :name => "changeset_parents_changeset_ids" + add_index "changeset_parents", ["parent_id"], :name => "changeset_parents_parent_ids" + + create_table "changesets", :force => true do |t| + t.integer "repository_id", :null => false + t.string "revision", :null => false + t.string "committer" + t.datetime "committed_on", :null => false + t.text "comments" + t.date "commit_date" + t.string "scmid" + t.integer "user_id" + end + + add_index "changesets", ["committed_on"], :name => "index_changesets_on_committed_on" + add_index "changesets", ["repository_id", "revision"], :name => "changesets_repos_rev", :unique => true + add_index "changesets", ["repository_id", "scmid"], :name => "changesets_repos_scmid" + add_index "changesets", ["repository_id"], :name => "index_changesets_on_repository_id" + add_index "changesets", ["user_id"], :name => "index_changesets_on_user_id" + + create_table "changesets_issues", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "issue_id", :null => false + end + + add_index "changesets_issues", ["changeset_id", "issue_id"], :name => "changesets_issues_ids", :unique => true + + create_table "comments", :force => true do |t| + t.string "commented_type", :limit => 30, :default => "", :null => false + t.integer "commented_id", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.text "comments" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + add_index "comments", ["author_id"], :name => "index_comments_on_author_id" + add_index "comments", ["commented_id", "commented_type"], :name => "index_comments_on_commented_id_and_commented_type" + + create_table "custom_fields", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.string "field_format", :limit => 30, :default => "", :null => false + t.text "possible_values" + t.string "regexp", :default => "" + t.integer "min_length", :default => 0, :null => false + t.integer "max_length", :default => 0, :null => false + t.boolean "is_required", :default => false, :null => false + t.boolean "is_for_all", :default => false, :null => false + t.boolean "is_filter", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "searchable", :default => false + t.text "default_value" + t.boolean "editable", :default => true + t.boolean "visible", :default => true, :null => false + t.boolean "multiple", :default => false + end + + add_index "custom_fields", ["id", "type"], :name => "index_custom_fields_on_id_and_type" + + create_table "custom_fields_projects", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "project_id", :default => 0, :null => false + end + + add_index "custom_fields_projects", ["custom_field_id", "project_id"], :name => "index_custom_fields_projects_on_custom_field_id_and_project_id", :unique => true + + create_table "custom_fields_trackers", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "custom_fields_trackers", ["custom_field_id", "tracker_id"], :name => "index_custom_fields_trackers_on_custom_field_id_and_tracker_id", :unique => true + + create_table "custom_values", :force => true do |t| + t.string "customized_type", :limit => 30, :default => "", :null => false + t.integer "customized_id", :default => 0, :null => false + t.integer "custom_field_id", :default => 0, :null => false + t.text "value" + end + + add_index "custom_values", ["custom_field_id"], :name => "index_custom_values_on_custom_field_id" + add_index "custom_values", ["customized_type", "customized_id"], :name => "custom_values_customized" + + create_table "documents", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "category_id", :default => 0, :null => false + t.string "title", :limit => 60, :default => "", :null => false + t.text "description" + t.datetime "created_on" + end + + add_index "documents", ["category_id"], :name => "index_documents_on_category_id" + add_index "documents", ["created_on"], :name => "index_documents_on_created_on" + add_index "documents", ["project_id"], :name => "documents_project_id" + + create_table "enabled_modules", :force => true do |t| + t.integer "project_id" + t.string "name", :null => false + end + + add_index "enabled_modules", ["project_id"], :name => "enabled_modules_project_id" + + create_table "enumerations", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "is_default", :default => false, :null => false + t.string "type" + t.boolean "active", :default => true, :null => false + t.integer "project_id" + t.integer "parent_id" + t.string "position_name", :limit => 30 + end + + add_index "enumerations", ["id", "type"], :name => "index_enumerations_on_id_and_type" + add_index "enumerations", ["project_id"], :name => "index_enumerations_on_project_id" + + create_table "groups_users", :id => false, :force => true do |t| + t.integer "group_id", :null => false + t.integer "user_id", :null => false + end + + add_index "groups_users", ["group_id", "user_id"], :name => "groups_users_ids", :unique => true + + create_table "issue_categories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.integer "assigned_to_id" + end + + add_index "issue_categories", ["assigned_to_id"], :name => "index_issue_categories_on_assigned_to_id" + add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id" + + create_table "issue_relations", :force => true do |t| + t.integer "issue_from_id", :null => false + t.integer "issue_to_id", :null => false + t.string "relation_type", :null => false + t.integer "delay" + end + + add_index "issue_relations", ["issue_from_id", "issue_to_id"], :name => "index_issue_relations_on_issue_from_id_and_issue_to_id", :unique => true + add_index "issue_relations", ["issue_from_id"], :name => "index_issue_relations_on_issue_from_id" + add_index "issue_relations", ["issue_to_id"], :name => "index_issue_relations_on_issue_to_id" + + create_table "issue_statuses", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_closed", :default => false, :null => false + t.boolean "is_default", :default => false, :null => false + t.integer "position", :default => 1 + t.integer "default_done_ratio" + end + + add_index "issue_statuses", ["is_closed"], :name => "index_issue_statuses_on_is_closed" + add_index "issue_statuses", ["is_default"], :name => "index_issue_statuses_on_is_default" + add_index "issue_statuses", ["position"], :name => "index_issue_statuses_on_position" + + create_table "issues", :force => true do |t| + t.integer "tracker_id", :null => false + t.integer "project_id", :null => false + t.string "subject", :default => "", :null => false + t.text "description" + t.date "due_date" + t.integer "category_id" + t.integer "status_id", :null => false + t.integer "assigned_to_id" + t.integer "priority_id", :null => false + t.integer "fixed_version_id" + t.integer "author_id", :null => false + t.integer "lock_version", :default => 0, :null => false + t.datetime "created_on" + t.datetime "updated_on" + t.date "start_date" + t.integer "done_ratio", :default => 0, :null => false + t.float "estimated_hours" + t.integer "parent_id" + t.integer "root_id" + t.integer "lft" + t.integer "rgt" + t.boolean "is_private", :default => false, :null => false + t.datetime "closed_on" + end + + add_index "issues", ["assigned_to_id"], :name => "index_issues_on_assigned_to_id" + add_index "issues", ["author_id"], :name => "index_issues_on_author_id" + add_index "issues", ["category_id"], :name => "index_issues_on_category_id" + add_index "issues", ["created_on"], :name => "index_issues_on_created_on" + add_index "issues", ["fixed_version_id"], :name => "index_issues_on_fixed_version_id" + add_index "issues", ["priority_id"], :name => "index_issues_on_priority_id" + add_index "issues", ["project_id"], :name => "issues_project_id" + add_index "issues", ["root_id", "lft", "rgt"], :name => "index_issues_on_root_id_and_lft_and_rgt" + add_index "issues", ["status_id"], :name => "index_issues_on_status_id" + add_index "issues", ["tracker_id"], :name => "index_issues_on_tracker_id" + + create_table "journal_details", :force => true do |t| + t.integer "journal_id", :default => 0, :null => false + t.string "property", :limit => 30, :default => "", :null => false + t.string "prop_key", :limit => 30, :default => "", :null => false + t.text "old_value" + t.text "value" + end + + add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" + + create_table "journals", :force => true do |t| + t.integer "journalized_id", :default => 0, :null => false + t.string "journalized_type", :limit => 30, :default => "", :null => false + t.integer "user_id", :default => 0, :null => false + t.text "notes" + t.datetime "created_on", :null => false + t.boolean "private_notes", :default => false, :null => false + end + + add_index "journals", ["created_on"], :name => "index_journals_on_created_on" + add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id" + add_index "journals", ["journalized_id"], :name => "index_journals_on_journalized_id" + add_index "journals", ["user_id"], :name => "index_journals_on_user_id" + + create_table "journals_for_messages", :force => true do |t| + t.integer "jour_id" + t.string "jour_type" + t.integer "user_id" + t.text "notes" + t.integer "status" + t.integer "reply_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "member_roles", :force => true do |t| + t.integer "member_id", :null => false + t.integer "role_id", :null => false + t.integer "inherited_from" + end + + add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" + add_index "member_roles", ["role_id"], :name => "index_member_roles_on_role_id" + + create_table "members", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.integer "project_id", :default => 0, :null => false + t.datetime "created_on" + t.boolean "mail_notification", :default => false, :null => false + end + + add_index "members", ["project_id"], :name => "index_members_on_project_id" + add_index "members", ["user_id", "project_id"], :name => "index_members_on_user_id_and_project_id", :unique => true + add_index "members", ["user_id"], :name => "index_members_on_user_id" + + create_table "messages", :force => true do |t| + t.integer "board_id", :null => false + t.integer "parent_id" + t.string "subject", :default => "", :null => false + t.text "content" + t.integer "author_id" + t.integer "replies_count", :default => 0, :null => false + t.integer "last_reply_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + end + + add_index "messages", ["author_id"], :name => "index_messages_on_author_id" + add_index "messages", ["board_id"], :name => "messages_board_id" + add_index "messages", ["created_on"], :name => "index_messages_on_created_on" + add_index "messages", ["last_reply_id"], :name => "index_messages_on_last_reply_id" + add_index "messages", ["parent_id"], :name => "messages_parent_id" + + create_table "messages_for_bids", :force => true do |t| + t.string "message" + t.integer "user_id" + t.integer "bid_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "messages_for_users", :force => true do |t| + t.integer "messager_id" + t.integer "user_id" + t.string "message" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "news", :force => true do |t| + t.integer "project_id" + t.string "title", :limit => 60, :default => "", :null => false + t.string "summary", :default => "" + t.text "description" + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.integer "comments_count", :default => 0, :null => false + end + + add_index "news", ["author_id"], :name => "index_news_on_author_id" + add_index "news", ["created_on"], :name => "index_news_on_created_on" + add_index "news", ["project_id"], :name => "news_project_id" + + create_table "open_id_authentication_associations", :force => true do |t| + t.integer "issued" + t.integer "lifetime" + t.string "handle" + t.string "assoc_type" + t.binary "server_url" + t.binary "secret" + end + + create_table "open_id_authentication_nonces", :force => true do |t| + t.integer "timestamp", :null => false + t.string "server_url" + t.string "salt", :null => false + end + + create_table "project_tags", :force => true do |t| + t.integer "project_id" + t.integer "tag_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "user_id" + end + + create_table "projects", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.string "homepage", :default => "" + t.boolean "is_public", :default => true, :null => false + t.integer "parent_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "identifier" + t.integer "status", :default => 1, :null => false + t.integer "lft" + t.integer "rgt" + t.boolean "inherit_members", :default => false, :null => false + end + + add_index "projects", ["lft"], :name => "index_projects_on_lft" + add_index "projects", ["rgt"], :name => "index_projects_on_rgt" + + create_table "projects_trackers", :id => false, :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "projects_trackers", ["project_id", "tracker_id"], :name => "projects_trackers_unique", :unique => true + add_index "projects_trackers", ["project_id"], :name => "projects_trackers_project_id" + + create_table "queries", :force => true do |t| + t.integer "project_id" + t.string "name", :default => "", :null => false + t.text "filters" + t.integer "user_id", :default => 0, :null => false + t.boolean "is_public", :default => false, :null => false + t.text "column_names" + t.text "sort_criteria" + t.string "group_by" + t.string "type" + end + + add_index "queries", ["project_id"], :name => "index_queries_on_project_id" + add_index "queries", ["user_id"], :name => "index_queries_on_user_id" + + create_table "repositories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "url", :default => "", :null => false + t.string "login", :limit => 60, :default => "" + t.string "password", :default => "" + t.string "root_url", :default => "" + t.string "type" + t.string "path_encoding", :limit => 64 + t.string "log_encoding", :limit => 64 + t.text "extra_info" + t.string "identifier" + t.boolean "is_default", :default => false + end + + add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id" + + create_table "roles", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "assignable", :default => true + t.integer "builtin", :default => 0, :null => false + t.text "permissions" + t.string "issues_visibility", :limit => 30, :default => "default", :null => false + end + + create_table "settings", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "value" + t.datetime "updated_on" + end + + add_index "settings", ["name"], :name => "index_settings_on_name" + + create_table "shares", :force => true do |t| + t.string "title" + t.string "type" + t.string "url" + t.date "created_on" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "students", :force => true do |t| + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "taggings", :force => true do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", :limit => 128 + t.datetime "created_at" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table "time_entries", :force => true do |t| + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "issue_id" + t.float "hours", :null => false + t.string "comments" + t.integer "activity_id", :null => false + t.date "spent_on", :null => false + t.integer "tyear", :null => false + t.integer "tmonth", :null => false + t.integer "tweek", :null => false + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + add_index "time_entries", ["activity_id"], :name => "index_time_entries_on_activity_id" + add_index "time_entries", ["created_on"], :name => "index_time_entries_on_created_on" + add_index "time_entries", ["issue_id"], :name => "time_entries_issue_id" + add_index "time_entries", ["project_id"], :name => "time_entries_project_id" + add_index "time_entries", ["user_id"], :name => "index_time_entries_on_user_id" + + create_table "tokens", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.string "action", :limit => 30, :default => "", :null => false + t.string "value", :limit => 40 + t.datetime "created_on", :null => false + end + + add_index "tokens", ["user_id"], :name => "index_tokens_on_user_id" + add_index "tokens", ["value"], :name => "tokens_value", :unique => true + + create_table "trackers", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_in_chlog", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "is_in_roadmap", :default => true, :null => false + t.integer "fields_bits", :default => 0 + end + + create_table "user_preferences", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.text "others" + t.boolean "hide_mail", :default => false + t.string "time_zone" + end + + add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" + + create_table "user_tags", :force => true do |t| + t.integer "user_id" + t.integer "tag_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "users", :force => true do |t| + t.string "login", :default => "", :null => false + t.string "hashed_password", :limit => 40, :default => "", :null => false + t.string "firstname", :limit => 30, :default => "", :null => false + t.string "lastname", :default => "", :null => false + t.string "mail", :limit => 60, :default => "", :null => false + t.boolean "admin", :default => false, :null => false + t.integer "status", :default => 1, :null => false + t.datetime "last_login_on" + t.string "language", :limit => 5, :default => "" + t.integer "auth_source_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "type" + t.string "identity_url" + t.string "mail_notification", :default => "", :null => false + t.string "salt", :limit => 64 + end + + add_index "users", ["auth_source_id"], :name => "index_users_on_auth_source_id" + add_index "users", ["id", "type"], :name => "index_users_on_id_and_type" + add_index "users", ["type"], :name => "index_users_on_type" + + create_table "versions", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :default => "", :null => false + t.string "description", :default => "" + t.date "effective_date" + t.datetime "created_on" + t.datetime "updated_on" + t.string "wiki_page_title" + t.string "status", :default => "open" + t.string "sharing", :default => "none", :null => false + end + + add_index "versions", ["project_id"], :name => "versions_project_id" + add_index "versions", ["sharing"], :name => "index_versions_on_sharing" + + create_table "watchers", :force => true do |t| + t.string "watchable_type", :default => "", :null => false + t.integer "watchable_id", :default => 0, :null => false + t.integer "user_id" + end + + add_index "watchers", ["user_id", "watchable_type"], :name => "watchers_user_id_type" + add_index "watchers", ["user_id"], :name => "index_watchers_on_user_id" + add_index "watchers", ["watchable_id", "watchable_type"], :name => "index_watchers_on_watchable_id_and_watchable_type" + + create_table "watchers_of_projects", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "watchers_of_users", :force => true do |t| + t.integer "watcher_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "wiki_content_versions", :force => true do |t| + t.integer "wiki_content_id", :null => false + t.integer "page_id", :null => false + t.integer "author_id" + t.binary "data", :limit => 2147483647 + t.string "compression", :limit => 6, :default => "" + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_content_versions", ["updated_on"], :name => "index_wiki_content_versions_on_updated_on" + add_index "wiki_content_versions", ["wiki_content_id"], :name => "wiki_content_versions_wcid" + + create_table "wiki_contents", :force => true do |t| + t.integer "page_id", :null => false + t.integer "author_id" + t.text "text", :limit => 2147483647 + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_contents", ["author_id"], :name => "index_wiki_contents_on_author_id" + add_index "wiki_contents", ["page_id"], :name => "wiki_contents_page_id" + + create_table "wiki_pages", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title", :null => false + t.datetime "created_on", :null => false + t.boolean "protected", :default => false, :null => false + t.integer "parent_id" + end + + add_index "wiki_pages", ["parent_id"], :name => "index_wiki_pages_on_parent_id" + add_index "wiki_pages", ["wiki_id", "title"], :name => "wiki_pages_wiki_id_title" + add_index "wiki_pages", ["wiki_id"], :name => "index_wiki_pages_on_wiki_id" + + create_table "wiki_redirects", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title" + t.string "redirects_to" + t.datetime "created_on", :null => false + end + + add_index "wiki_redirects", ["wiki_id", "title"], :name => "wiki_redirects_wiki_id_title" + add_index "wiki_redirects", ["wiki_id"], :name => "index_wiki_redirects_on_wiki_id" + + create_table "wikis", :force => true do |t| + t.integer "project_id", :null => false + t.string "start_page", :null => false + t.integer "status", :default => 1, :null => false + end + + add_index "wikis", ["project_id"], :name => "wikis_project_id" + + create_table "workflows", :force => true do |t| + t.integer "tracker_id", :default => 0, :null => false + t.integer "old_status_id", :default => 0, :null => false + t.integer "new_status_id", :default => 0, :null => false + t.integer "role_id", :default => 0, :null => false + t.boolean "assignee", :default => false, :null => false + t.boolean "author", :default => false, :null => false + t.string "type", :limit => 30 + t.string "field_name", :limit => 30 + t.string "rule", :limit => 30 + end + + add_index "workflows", ["new_status_id"], :name => "index_workflows_on_new_status_id" + add_index "workflows", ["old_status_id"], :name => "index_workflows_on_old_status_id" + add_index "workflows", ["role_id", "tracker_id", "old_status_id"], :name => "wkfs_role_tracker_old_status" + add_index "workflows", ["role_id"], :name => "index_workflows_on_role_id" + +end diff --git a/doc/CHANGELOG b/doc/CHANGELOG new file mode 100644 index 000000000..ad808770f --- /dev/null +++ b/doc/CHANGELOG @@ -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 # 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: 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
     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 
    +* 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 
     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 "MjDYeRO@*L;5gcIW}-Lfz>gT6%FP@y$%rbG}w`
    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

    WSlDT0xQsH5W;O!V71UOuK$4jW zS|Gu+kfAl;(tfV8;o!=?&6=$cYNBHnXVEva!Pftfr(_cMZ;qY?tecWT$ zbK3IBO3CKNnZZ8j(|4 zUz{P^G-S>!Q;ziWb*5}6Q~swt+hjV`IZ5f&jy>jd1}qAmfg96^|dlM}&* z6~QNExw)b!4YOmWiq*}q!9goH3d3$m)VvpUE57aZ8G8(7@$#ogGrD~_v~-CU`Q+k) zIa=FP&G@2l4FcB>86SDDi)>-^_$?Ze)N_NjseHCAr!6!J@kC%DCnDBW2{L^SHr@$H z-v@HpoVg_1AB28aabM$lz6v$*X*9Mw!@kN{$mk3Dwc$d6W=ZdST<5rs`(BgKG|G-j z$&UlM8g~g~Nl};*cqEFLsnj*n>gFBLsS$_S;M&V{EySi7F(JzVH%Q1(#*!B8g`3fZ zKNS=L$Y`UfznWf+2?$ZETjCbWfQp5Zi^I2+QEa1?%@FXIk}V##0|*hDwjp&~NRE>A z3|=4Y*zX0vl*wUwL$cH@_~@|mfE)`DFapo^O~vl6qoXU=a@uu@=5 z$!%z9P7#g8gG(`?vN36cXjEWcyPs}jJm0B&Nst;c=L(f&Y z3x^R?IQ(dmHKP^UHIv$#)#x(hNg$0Hjl~Qblp~j@!2fAI*Cy)$wkyB_!$l${gsCL-gB4waRllfy{FzUwFs zm!R42?Pub<9!;50x6)tUlF4UI|gE-C9a1e-NF$y zdXsF3C`nP`N!l>t8J>y=q`|cDc#&q3TvLpJc)8bkf4&>s87piY4o*B!!9Q#Hz6*@S z$Q~H7yW$6n#DqpEq5)V^4nwFubR4z1s7o>|K#blXGnD zS@F)nZ?X`W$9Fzr^;X(=s7Mxm5ctF5@9qat4k=b)rC}*<)JV@+vpqhB7$z`?sFXog z*H~CJ6-qOl>oErj-szhnV@BG>h>CxYD@NprhWFNuK#o>+`#Vkop0q@!Ip*Ndz8LW< zQfUobX)01_v)!~G`Hs98(Zzdv3$CAe(8<}8i-!0JI7CGuu~gd~)1o|ap;4dE@qijK zhVj>X_k8lSZT=O=YDG%}X6k}bk`@Yj31%0|*GJfgTIs2T((7I?W#N6&inhKnDaxmL zK5J2A87Q(PY<8}NW4+K0xFxAy#mhZ?h@-_KV{<<6>XM|DNmxZNhh;miBy;|eC?S)6 z$uX}&Z*MZ#p@$BhDAipm_;$`3TESOR&bcs4Ek1ZFkb?2>@G;2_1y7_)P#=OP%{kHR z7Y2&MB@dh8C-Wb{;|20ntKfc=4TtLS_mcFWUSPEBpJhDF0|7+_=`z&A5+xS1(kx^} zMMV3rj^~!0mfD}?n{;*$44R$*>>VKdYT7J;U5;7>#gLx)qN6^m33GU3EM8_fHTUA{ zeMxLpupj)yV8=FAkVLtzT4B8n&84H*m+wFl>55Sqn-Tay%hWW9^n&{BwCS6_j5HhE zO&}IBA}9RiE^KmQMCkOg`uDLgj=e_?JObCEjb*$4;YhGxsiXA1Mz;T80Z3fHOlo>E z-~gA+_P~}WWvhPjcnRwI*E&ZALQ6&i>-ro8YA$nQaBAqOVer3ILLeRj08BF({&|Ui zrg%;F-NOYPEX>Wf7&WJF{SaoD{#o?DJylmi0usPiW8umG&;SZ3Ip!_k(~?;%0DvAY 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


    MhQfwV@pTM=YsOnSj!%(& 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Π?F2OECD8<0B!twp=`+LeGzWs~|B3wKQKRp<9 zOLP;({ls~BuNLYHb3c4ho*&UN*w%UwpG%X~n8_O6>@#9wT>-)2$rZRi2velWbjf~A3E{;o?RNi!|WMOluQgRdHum=(gi*z8o8wL1d{<`5h=*%%c6)0q%Iv(C2R=TP+=`V9q7|1CQ zOJJUas@6@h1pC&u^@oWzUB-%RHO|%~x-F?{gr$atxD)%?(AFTiytM^2X`U^Tz76wZZ9g4NXLU^8gl+CD> z8AIuq1@QWOoBOj~dPibmPVOKk!-iD7KCm5&tx8;e{iV2Bd~YQ2##j?;!F2-_Erh{D zuetrwEqOJSyj;2Q((5fv2jAc-qqj+PXkwzEev&N_h$LQVDUH$DlQ*|@lF}vg*oWPV zM@n**FTUH55m+TiW2xI9lpW8h+Y#s2G8kf81MkGDb z{#f;ieTUuX&L*P)?H`*58e=GR2^cB;F+lAGyS5qVReASQ%E@4L7qlV;B=o z=g=ANO+09w)*Wn+=C1;c2jrcX-fk2duU9pADKxz+|7;w>?-s4Jq$^v!S{E&HaiF8b z{c|quY_3WYBRPYLQ&~>2jLN$PCK>U$8io(jA3ly5UeI}CJ+s~)&o7gGkSUoG`dRB)(td{$9r1ShJRw<~ptMhoS-8U3D+TK66F>ceq5YpA1q^WFlC!dV+YE;&c z#$tli1p!a31e3^PZG7m_WfT12Ml;JLf9OKymD$b(X}U*)o5J(t*Be;!X08o1NX(s6 z#4{}lyk=&tM1c-u*6U;aOFjT$ya6>zC2NQAbEb+pc4vpx4pdo4kL`w$)R(-Q0vMOR z2OmqrvX0e9gryZ*Al0ZX9;{@$ghO}vswguREs8Xd>zHq(feGs8T4~y8k!N2=mF;G= z2-h(fT^yp*!t@3wWEP6x*RuUDo>U_Utj8{x=~aWdi?1L zE@y_y+{D@(-}Ghw{CqKh?bvaV{6rGRjgj67w#K4@^0Cr8VNy(@RRx(B?X~4f@sa2x z2)$z=IFOgV%<`IdliXvmoK>$>jkbBpnPYy8SnGUf;Ehoa7`f?uQzWcx z!e1Egf!XN5)wQP-*k{mJeHtR%^rrhlkTF%&7(vL~z&k$)nQn^{C|S#_?ATI+EyiA5 zMP2%emo4oq?PcnVUd*J%?{vuA!@K2~7&A&S2uIv0(dJ3McXG=dID7v_NE>fL-6~6E`+8XugUpi%4Z1{sth$7t zTR#Y7hLL;Ie%Hbr1g~HkKcwFEb`OB)4V0shZ4zn&rV=Z31(XkUQe9vM9bfUOnl5jo z^Pe!2ksDJgBs^z%u6jK*Z(Sj^kVbFGt|k3~gq}rELoU6HGwuVGU2y506^@4)9E{pm zqVJEmrgI}XbxSvQwsed9E+(!o6%^9^WL!KYdTAy!D0BDN3riP5ptfaZ97To&a+~07 z(1Emgmm~ePInh*r>+sR}(N~tW#|YfVe4r{sHl(gPvHTedZ?xFmO7Yx-QO%?^gC$50 zs}Otm>PUFiOmtvhAbf02s^U|qVFf4_AUByT^H=7}0}afaJkS_;Owf|*7WEey(h+}f zuEVeK#*}U51p=+NMhgSUeqSy>yu>@S!x$B@G}u(0Q;~mEBFqW5ctrZqMRoRR1)QOJ zN_8<*k7G;PQ0s^U)AucSCncCV~FCATumoivR^aginD<1y*Hb zxJI}wy2tl5QZyLqOIjhC`4fgs!#U!Ym%|B^a*Oj6_|jGxR?KLBOD)#1H>LtR4T(3v z;No-8OKE9*7E1+4XSVrp4`(VU!$VWMOZL9b!M8AGwLa7#QZkmK&lxgmk2=lRjvj#Y zjSLUo$1Ml1w2N(aeu8?J6TAJA3Cjr zP}hjhRWft}kVG_KjGCr3V^oWr~P*$#kk~xfhQXf<~Zk2u%JaW92e8VJ#L} z_<5xUEF~i1Sg33*;|^G6{g-TIL^9RJ_D_lE@a)rV$%N~8FaEN3@;0UTZuFt(=S5kj z{>4~we1Dr6GbZzx-Hc<5j}^0pB45~X+_}pcW17U=&{) zvFgzt3qJC5p?RwLfq%_Y>__voENiQpH1gfSQipvV+b36Q5M(v6kBg;cgk6PMoDxN4 zUOm3LfZxnbZmG?r`i>|{e!I|q3cj&B`JVxZ#$-4*{4oqw-s9Cf% zV;QdAQf#4RzJob<&C(`jFva|e2hT9oulH^YR@u=ZjPHGpwK^tWV5#u-QypNfu4=?X zG04DM{Vs*a63#@;C98qrzZ#~dvuMY*%`uObAv^+v6q~SQp$#n5!TbGG_QYBv{-#-m zw#?@_(YxwmI1gsp0tlDx!AYK;uOWVkTTL~!VO=Gyuv>JIb0p+SzSU;_wRL6gsyG!F zLj=58yW#c)P7M+U-P_^_3)P9P56fCQ9=1gi1FwtKqs6^<+ECj7(~N#aPQvv}2Cbmb$e|hp zpO1pN2)LLxvSrhdYSz>1I4c%5pUT{6{OJh_3ZlWi6_Z@dOX*Y|lz4Wbxw zq*DLsBr}lzSSe{{&C@tP%9o>+(x%Of2eT7e-XMgq4`gW^4hhQb{lT(%fZ4&l!9$iz zq@B?+*RjrF!)>Y5p~8+3)kb`_HHZ=4c*zLSHr)n|yrLC5n(hNDLKf=&hA@uFj}3C~ zC-+wAUYwfr24{YT{FPFJ6L(fU?6fbt+q(<_^5x30J^v*DIswn<=1z#AMGMp?#Q3`c6iRVl>_PNJ>0n#51u zO7SfTP=K5>!%BL4#v#1+4RiSK%yDs}) zd#cRa!$+&B%!q6g!`_8{s*_lG8a;bIqdnK6qlE0P8neCxuC+-S)gm}6oF<0`!~>t^ zQ}>ERr$*}%*|a`OKP{L^`|x$9L}f3{HU7E$HGQjK&?okf5Yu{X}bnolbJwAQ*K=mR1Rab|&lPUQEhWqlDLyD<|`Gs-4}^Ks6^yn+fZ?Pn(#H=Hvj17k%ZX~0#bv- zIha@NsWA3M!3vK&M@XSWd9M8j3%Y*sPD28s2=SH2?Btb*208xr7lP~<;nq5BDobR! zKL^wLI_!Ky0OmwW(z$r@uQ}dK9jsUTr>3jNTtjK{BP+wg;507_-LWDjIJ9lGe4AgG zQl)R5Tv|+5WM=}kI2O7zYteFh85Xvmwk7$+qCE+QiS`y)aE{~`xsd8i(aIbS@EOZg zf7=zjNLhZYeMKd4Y+eEf; zKaDV(eMI$PnVWe?#4=w!K3#XA;9gX&ioKQ=faN$t@Ldfd>S%Kx}LKGCLI#2`*L zaa~_`tx)8|cM#HM6}p**UDg|ObY~K1@nz421(bATPpVpAZ!ZSV#ru@1Eh$T}&_pA` zZekNsDcgqd8Day=yGRa$5u#UyN!kId(>St|Y!4%Ufh;_<1xMh)&WC4@?O$DlQv*Xu z{dM>UlUVBkDB3HT#s{?-%!yXSYG7%S5V>Z}GO1J0)i{&x!gN_QLkQf(BWL2Fz3#2> zNbPKGt!RmXgKVwNhX#e5v+CR;TzziQ%jz^-eNKWOObYYuG?VL%FLb%*Z}(leuQ;z= zd*?&8c>BHTLQeI&+6k7)I0JbYaZ=NbQKtrFx;I@DhEVMdmI?LLxvE@mm|E3H)0l&) zh?<`%YPgz-b&ULNw@0ykYGOv3ZN%QJDf+B%?f^pO?6J`>C=Xsc$hc}N;v6)jSht@K3mp+`r1ru=%P+jgszc`NIsV$dn!cSZ&9HnJ~ef5^*#6Elkd z5)t$@$*?fsC&-s;PcB0uA$TV#;9I-wWf$fAJ%Rb*!Gc;M%8n@5Pc_IC*|AXO7nVcT zOmIdO^BMylhKCb8ryHL5l<2X}B7|_sj2;}mwjzSjfj{_9zDX9W_5Sf0z=sQi0EssN z3fOLC?7z?WzvOr`liFVdY$tHXKmCLuYh{U;W2(opr<2B(u3z?N89^ZL|L{gULuD!k z>5fXV1r*s$sUz4LJe%$e3s0x1vRqqZH>GZSYhTB^H=#TNO`fl*sb8$`Cu0enzj}Os z(Nt-jrvw!09(<|BKhL)x^DRY-;9^TBkHs+@!OutirTKau;$$h;dEBy0Ae}Bn#%mwv zW}o&8>=&LAQGCac5yA>vP{%hL1cAnM$u52%fb-9T*YE}aMbd@H{xo{rxMJtmJy|E3 zR63~=IHU{Oc&*Ho_-(V0XEu!PpFcuT*B_0V%nl!PU5qO&JZ{uoDlW;q@>&zctwfOb zV5FX=GpZtVjRi6TMCyJgO)dj;c1JazDC%NjA_&)0@4M?^=HCb$-*#Edq<92nP=3yb z3ay6Un>$i$8g-X`$OC6I9CdKMe{@Pj5;(>X8orOZ4j^pw6f9gyK4BC|O?@nbg@w@i zX^8e2y4U-$P}%zGrx)6KsukLG7T8KS<`+cgPp{Q^l&3w1Iu=f%sc~T0{3l;reJ7<4 zylgJlbv&i6;th8#-*hpx6fa8{)I=3dvmfs6m!^Y_m|IqkZxfoCh3?wL%U7zB zjq@Y;w>?6UwrM&U>))WmQt@5AC$6A;{XbZZx|6QEMy^Kus(v-Pi^}|_WyLy$YIesG zFG5@C^A7yy?dEpZckYk)?!Z+N*^m0%l6D=zDQjbc=J_dExzSB2x$I+J{B$mKO790l zK{9;Jj0`)MUbo8R38CN(;E?Zb0w=j zvxm@$`cpv_|1@Y^KUR(;O$yN$wrV?6KA_O*SLQC;&CYi1q^j>G8wnT0J9`clYnlEi z7QwB+0K)#mJdeOyUgNibK{QwzCoskWgSeZDs;2(KsA>I!DxLe+aQ?q_K-~9X);p8C z-ubU#uURg9du=<%m7NR{9Km@JhI!g?^1ROZ332x?CAvS;OGtbs#~SJ<$r(!6Izw#JXwnKuB@r8s={B##0~Wgorl969h;c( z`s7fk?QO%X+S=EAT&yAI&E;b_bM<1xN42hT5`pFre;5#FFDNpAQQvdT!^>vHYrPF& zF|+n==C zzxn+G?apt0?thMB`_0eePa6Agex85QIDYf{2O8&ZeqMi$Xa#X)n+GIZpI%+Jm!y(!_rABmR>H-o*D`Hss4c(C+`{cka(|62JM8 z{7IAi&5!g?n$&N8|3H)e&5!KQaWcR8o&S?2`B z;)T0_qm`xIa{)WY=QdX2{4bnr!Zps<;QZm z-ey~~C-HiEo~PJjpJU?ptesIp@|3wk>o1q-Lp5#LZqna{6la~yf9`-BOnG8NO8@%S zQgx1y%q3EiTMsogADq*=U6jc3?P#sa6JgwV;Pa{WXeRLG!A7VK6w%l(Q@GO@fUEm% zmWsj)5fMG0<0d5{8iz5LlBM2d$mH zbjf0R@Qi;cm*)Iz0P}i(ty{)dr#3fjW_kk@|v=0%m=);iW=rE!WwZaifO%`e|Wi91O3r+YbuD0x}e?N8FhjyP)pOcsEbUz ztr+9&-~%Sq-c3ueNapQGk;8n`$=A+!TIeF=v+GI>lVn+O#A1?(lToE*cufRf@oeJd z(d!I$6+2*gDmVsi3mT$7`v2TD6f@M;YbiIaPryEC@8}SDpr&dMEd#QMnkwTCF);I4 z$xk+$YV*e%&=qZh!|St@kbKER`CvJ zn+99L3=*2`IXAp+7F;80}5Pr&^^y1xzU$(y0k@h z9zh{|kfs?=t?*~{P`c=FubV)_l=d|RtE<=`8;$zD-G*GxDh#EwS71P>X`+smN0cS> zy3!M}?*`~q?V}8b%+r8PikkWhtoluwB9-^YmFCapbu|$Y7b=#%grYTWjFd*5>|H!! zwZ!p}f#=e`jQ}g`3+2oI&6X8`D-Xo}FmXlnFM^I%b7QHPrSL5|`SIhiZv*LxdTEaY zjvDCKFFr!QWSsfA_uYi>=4VS`e4#lJX~hI=@;h47fS#LlX2Jck@?efUnuubF6mOMD zr%UnRA)09BP7%GebqsgNsn~nry1r>=RHNN6I|&Y@iih2Kr!@|gQk$4wVOajF0Kt4P zp<9>YJ%oUwWGUkuAelUy`%N?1)^uojTdUhR%aYyWNw)d>l+UH~P33!Awex`ovtHu} zh{24J;N}!k^;L%7Q7jMiG?EL}c(!#N7)ncC0kANm-(UT8*E*FWD<6OVrv?_LrEt5Y zmvP)g%F!yG%CW==kS2eh{rSuM*pi1UVOG~T?Oa3)H3fTmKIl{Uu07sq*y|$~X!vN= zokT5rjG010)qd$hh4}!v)+;l9oXSvXvl(s9y@%SlzJpKH&rm$W_)(~NJm~3nfj=vv zzl(BzK5jLcWZ#G!j&K^cvGP9=?K)a_I-P!zYA#VqzeL1$Mj}H0oE4ZjvL%j%5#1qQ zCYsis9uM>j%dSkqkHS&|M7dexVWI5FTK1#RatLb9HC7HGrFX#yon`O@C$TrK_~a}x zw*ag0er`g(Inl+s^+Um4D6bau}u{S(kxY=~!T7BR2td+nu zZHPQE@C^>6y$G>r9)t2~lfhJO6LyMU>^0CYeyk3r!}jH}h{Y#lhL5iwC_cGeBGOVq+3D$}OMx5`v8o#} zNEwchLpRs&G#%B?pKR~-%bvEf5VAP@fcu>fJleu8cbIUKO3(YQtkGoUX!mvw312J3 zS<$jIQ^5I+S4{?<`zb1aOt1R*(Kl zwDH1-Nwc9~k)44@w88xx{%CBSoX@_!krtv)j^nmIC;oyscL?p;;k|mEo-%%zzTojV z>}0%y1$JDOdD4?H4#S7S@Z0q}39^1T2UYa5O%XvKzvt`Q@v{b+&k#|a21_H+0*#OF zP?1U?XDpNk6Q<_b!haSBHrl3s01w8--&5l~{hcIdqiO}21Wg&gTgs78dq$tkmXr^} zkOi%e?k`_t$Ym070M?Nq*Jm>o<#*sDAmecBZqhYbK}Ga{6VBkhktw0f91o`O#Y$IV zVP>H5O3SR*{K?V$=^TMRD5F7+n=~<+pmL>=>c_6OjOf-r2Z4cvRJc3hma6DUSM)U+ zV%oDNQ%Joso~l{Vk1G&m)Ap^ptpn^Q$DJc*joI`XyeG6$7@ z@Ps#0(Ujj*?T!ChJ$7i!n2B=$rkM=LrXnK5wBC~|_w3T{N_R59DX>j1wE(Pix}r-V zBveQf^cgsGulaxjVAQykiht>}!Iu1Ea@f-&I9IW>)!UvMS-{%Lq3;U083Z8xZ*j%>wXenWFXeb~5S)+T2u(=D8L>|r z;|N&YUu%j=vJ@|^#lHM9?Z?2h{~y7V>8A!100uv;_uK*oK7Fbec#uyP9Wf)|u6y?U z+@z2rnjm|?PxHJBIGvoy4dF*lTF0X#G7l}BgUKQlLHExq9Md4;xqIIHVR znjdcSzRzyn=+zQF($6%&>wSAbP1BmhXYvasbSDcGdJ-p|)u&82px3=#B%}G!qJt`t z>WV4|KJM=L7SRL4hikj4QD$0?1H#~kcm<9tiAU4;xmzuENKaVzkV2yl|` zZ5(M@J3O=@cSS{O{0_FarfU&qjdeA)11*RZ$gA0Bn1XI@(o!08^xGH!C%?UcqqL|G z=mGkf2N32IO$V6)cp+5;sx6AS(#%Z^dhRkNLclTw)2*k$sgKPT)R&$B!nlh959YZu z7l2u4{+{9IwD+wS60on=MXJw=7o%^uFC$Y94|pahD46}O6in448l!n1Ane0+iA+}cL7Zg+%JXX6F<=!@@*`xTTHRZxbMEIY19P*XQ4D7G-i69 zpuf`c%hzmH^_Lq}DU3c^f1e|^QFEo6IuH{CFtyQLLBZ!672Krt=~*6!<0yg$a`@}v zEb#p+EqFX0M)(ffp00I1C7hfRc23KeOK7zQF_>2BLOHl@r4(+$LgL5#$?Uw*V$SV# z|IKrot1AKLiHMwBh05r4`5k6H4R!~cI5&!ToGYO}c4~e_OvbA@G&iZbB^`nyY@nP< z=z+c49nsO4gp=r9(2&Bm0cG)E=VmbTUJNE<@dqj#WM_*hg`B7;O1ZDTU4MDBgPM=2 zG)G^gIp=v(?}C2Ys=x3APWw!@Th;TVGeis4W2S;nKfPGQW0#AyDqQ7|4^=sW&*7y(VE*^=9B|miQ5KP|Yu`ey^S*K{-lk zHUo4de&bU|*5L#Bpa95ox0T|Eu3*%0H|j|cLj$ITd@=$Gb+gx@kxhEj&;7r`(*8I^Bbvn84s*QMU&yJn zyzWl*UQq1_*sePw5!S^L@7{d~-+PoG2k)B$D^*tH?%DKM)bQ1JIX9zQIe$LddexcA z#(1;XwDX?P)hdIdx9xdoHHRL`XVo;VbB%t$qBc0q)&XI zTz2E<9Cb>(o4Tw$MIIGqGne-@rxVj6=0GHSggTu@!A_lFM<&pz* zcHVzat$SSC@j1224>8!DSPAn`*hB717mNMwt|`%+GDR-kCD#=+bbY*Oh@^SMw;yx3 zo|WQp)-%l5Zf2x&Jc5|_FLlZG_t*U>((>enGf89;-}|j;l_#JYjD|U{3TRI5%keIF z*>mFX!pcDfvQZaFKhJqm88-Nq((AHH0ncWvnd!UEHA<<^4`zoLEC^=-I!jWTpge|K zN=%O`ThUpfqR32@iH}XTElD&IlqGFXqWmm}4{20fh6SEHX&0|-z*_LG)#WKOsZ~e5E;FjKep^rOy3`i_D{@|wqtunoy9~G1;a}w>wE11i zcS*b_#44e3bkR{wdFzD}ZP*IXPzfH=?&`?f-G-Iy*12oV)&3z7&$lNZnfgt>6Sj@G zCpwhD6@Q3FrxfEqiJU;M9y5G5>aln(VpZ+Jn9f_RPtj-V3}IOSiB4@wHP-5Kr8pOkGlTET;b! zC;eA@8qn2YPK*8+1BzmcLkFx^SH25p9$AqbFauR&pHGtW^Pv?RRpxJjjXyd5F3W=1 ze)t3UXt*)5>-3dXSIqm25qukTgXU49s>bKnyZhM_XHLDch;(e`d>5KJ(Oh0 zoCz|X+mO4uKc%5{BxEjX%&f6;aweJA!s4zy!Pew$gedA9!yqCzmsISz~;)xL=XbFUF@dt*qw#r3q@(ytwhu3d_&s2RWYKrY4AU z#p@-9$a|AU6~MhyQ;lvKRi2Df3k~dgbN3U=>>OijZ(b!c+|)3_%^2|-4I4454YiJ7 z9{42JtQ3yYCK%Vz)~D5(|7EFBCB}EDJ5t2abSJ&nAylbYCFQcJ1j>0VSJ-2=^ZomZ z38Nv9#}{I@6b!M7HIrmaN<^`xUCNDTUR^SHP+8#J9>g1CF4O+kM36;gLDf6+-pv!k zsB|_pm0838J7`^-Vn8wf3rdjwbGFz-mZtTT@d-mC5wB6@9eEn(q*t6V+Meg^Ih-Yy zl=}1JJ!d9<7|ONp?m^dv^0`VZU=yPWYU6XfdROmo>Df8ggx!|b*R14M-dfX!ac=fJY`r#m0)fX)!3H~ z!<)#?xqLbmHfTijyO9k3eZ2-dxiR5Me(khy?HWx_^b;gBPFtt)$^9>F#~nK^#sg!sW&kDZeR7{O_~S8)BTg9{I+E~SYvtj4 zK?#ap644;xCgPDl8TwOsR&u8yH^uRNg3W~MYT!P|_i=5`)_VcyD}XxQU7%?lEj3^P z5PaOsuQ#=XdHd6H%-;8YlPZC=R|x&eYb2uW=qHnstVpsF>G=DSY-0Fqku0|!-k;i* za!*r8*Ic_kRi;?wJuz-iyiQkNVp>>{cVN8G^#m^d#D!~LPrF2=fRi(RRDC#ZtfvNf z=2^9&41OV~Y1giIkIl^#y(?HVYMh+#Nn%QBE^5zmNmnqYdTHcaK5kV#@(_gdX44`; znZmi9Vh$4n+8V-4bzag26pF78=KOX*cD_&}GjM;@AhfRIQu=*2kUbVTnX~2`zuP~; z@2sN0HC-wWN3Xn+f^@e>r850Roh*`mFMnjb);xn|#C-pSa@plg?0_9sOGF4k)G`CUFtGn6Hs@{8PSc9V zd+!|34_y>RP9;h~C^K&dK6S2p@0Gz-uVBCXrXVv9y`-j*B)3z2?LO4Ea$TeH$ykr& z?WzatUKve(lZ^Q>Dk^F$^VdJQb~rpq(S52CkS*5!Zl$y$UTUq($O%fEl{7aqExF@b z(KFU^@9LVPFL2#`cKIu$L8Y@=es;Z1vVvlNX&6t7`1tV2#L=%0RE@i#vy2xfDl9nE zKZpk${`i$t9D+1>YsvO}{BQjT#6LH+`u5F_0_pH%|Hg{L1ISR`E4BdWt8k#o~(~Blj6j`7(~r+xRDMOr$wZ;i3?X!NANAmwTYtf`h@4ye&qiHEqrdarHFCSQ zbc@&Ne&~Ji%1OoIa$f$0JyM5~cFek@#2W*N!)U+rCmm?Nig2@@hoPG#A z#I=~6YfnuQn=3nHoP6Jur(9^*UfUOceIuQC%{zEx)<49Y*f%*TH$tQePJ%2Ox9Y4+ z$*G$Vx@c@k?4La4NO5N)?%r*r@^FItSakzeywyxKiG{;`#ag=W zQMH<1Vr8z0km+)Px7wxN1rGR1E2*q|>|q)Gk1$R|+;@=Y;l7ptl4+?mHvJ%yG1msY3c4>n}`97!KDl7DiN9 ziqRWeD#jYug`6la>tZvFCqe~edXP8jAV7eKMqFwlIm90uoH|};`;(=?{4EyiQvc&G zB~-^-K4*4*S3%qsXWP$iIQ9u2qmcdDv)~ca4>e-a!;+0k=5IxEd38ihC#$1Ku2|?y zo75w;*f;hIbkmhp)WWYvmTC=ym;Z>f=YCQZEqG#0d?$vhBkf*L+J~eEd^w&jcU_{Z z1=zx1){yNbQ)4-ul6?f1uv+O#jg`Q-yZd;xL;nItZ$X6YGb8@La?0rEKu`n{cWZ+` z!9EZ_sGJ4ylWF;?-1QRk_r$n?4)I-oTBWF?A=kFe0V5%Kw<28Do}YfxwL~8Mr}^d% zl~H0<0T!2xhJ4sPN82x^?oNu5@>_SACHG#cWm{?NUMd0#DON@CQogW1B762>DZREX zuj`hYR>70L3=Kw(194Jhnb*ir^ToO8dkPMQvHncj&nn1hZC(|JJn0T&Q~M=_IP{!D zS6Ug@%1hU%Dl_G+x(n#`Fm%#2RqKZCv*8tnRdz3zCZfuCRG5fp;lRns!dN5-|olRD$CBeYc!SRN$(nq(ot(!xiTs2 ze6isj7w;uyTBs)T?>iPZ(h}JM~$ADJ` z%?IK(jk;kVtpxVEGFNDd?0&h+V-WNdc_o=erVVl_$PZV&AV)2HH}t-Vjoqw0CrwQHXy;UhGUSG)?|;*!<_fBkG@Bg?jVJ zic;+dcmY>r6-L_ zOL9wT|Eb`O3&8y~#&c+7$OIUd5;PC!bHKL0CD^*X-Po&HpU1VPZU2(QwY@7hp<~zo z*Rt@uDf@KHy(>X`{`|z@Y_;Ri+_aPE(OFKr=BnDhnu~{r-+iDF_xQ*y@6Wlb^BBij zU@s##%Rg0_-(>)(yhN+4_zO>ngXPh!%I4c5aS@BFgSj2CET< zhPh4+u6;JwgumFFr~rvf+x&4255n=!NIHS0y*^2yQhJ%6U*iGx+4Djjnc5$8FdrJ* zJ!XTdq@*;ie;hU(s-=BTFUcsRy{6RbZ#evnaRBkjRm`#KOWRipd{b4*xtA3p{d0~y zF_AfEMV4I+>mN)Vd6?Ryj&1&OOe3G`?Me)y+HGu{_9kfV_08uDqpo zkbzkE!$pv2HsCI~WvwX~RsQs@Z;19a%g%M5GRRrS2dJfLS{pKMGG5_HyJWc?_VH8A zGYQl5N;;LM3}S3x)e{9(k@P$F*=#^Q-$+VP+M5`Hwz{ueZuIKMadQm5_YQhKF&hmg z3|5nzNIv&NsMb1u_tIqb?NJ*vi0EGl+4R}wqrib10Paw!ISl3#5pwnZAU_8K`~5n8 z!auZ?wAe&T$2;>zGPJFIpLe(>Vc~n0?Y`e1NSNL75X;P-c&YVKq~4B^xLA#fXWC0t z=Zu&TUp(kp49{)le>=Hd9xzqV`1EMIoXdHHv0sXD#)qmv>ai%$Pow`r#Xo`9{_(## zmBYypuo=(a(=1ye+!Qy;Z)dfmWY8r389nLJea5W}m$hQ#Q$V56OuJd&NRcOczszBN z@(IaIb?ThnMq?9dHnyUZR%weFMMICe{uZng!%9X94| zT4Xt;<6U~_UjvFZ$T z16u924VSu^Q?!l!EcrRv7Dl({vUIFj-j)e4biPs3kJxN3ihpNhTw9WMV| zc;=){y?3(yK!W{==!4;E3EOTn(3{QsM}cehT91WH#v}c6!b~}KKvApAy*J>sV8h-M zq}^j>4p#vH$PBE=_5thkVoI*J05x82r?d%1RjuN$MO1Y(K0WW z6HqEld%l7sKdGGdzsLU1CcRY*WPA(c{&_QNOauLvF!wN7*!PTKrKNHN_Z%;=){Xql z^CRkW?rrZflp{AkRjgIKj#^Q)|G!v!3#d4nwOw?80R|sjLk1^Ua0r29W*FQxSa1^D zf=1B6-JRf0a0vu=cMWcVAb~*85YF)JZ~uGmv;Onnd(XPHR##V5S9jN2GhJ^z@B4K1 zJ%~!BpPK~4EhfwlHyPAv@cdF5;NSLHsiVu;GarPK$vg^Mc!HW0p*Sa}i#8Sc!j+c4 zwE6Pd4(4s=|2Z|Ho2byO5A+n+`5JdSS*tc|j$wLWJ6x3SFLcaDA!}D{)LOED%eGPr zHJ#LDB|W8o?LYJ(=z;2|hnZ@QD3814m#c{=FPGn!C!+1WNrIwM0cAsJe5;w=KKE<@ zl%fCb^!eQzYt++#nlJuP*-)*1;g@+k?PNwxOPlt^P1C;luwJ83S@+Lmz5)tsRBV&K zzuqfM6rm~TK=H|x4|hEIQQy$DO%&u7ko9yaoYFxVN$rwSMp{{E&qtsBC`uV^-XDH9 z@w%t7u+sg<%I(bs3Tq8XYT=iVA3V>!MwvxLnnF9e=NG6b1uT99PtzBjEAAY`FRca5 z`i%0`zvVK5F|3R{n{M-Jwt9+FEQhxY-yWUD_j^faUUZhCIl)U!)=@N-1r9Xq56}1)D{y+31ZE4(?H1TDk=w~dB z?va?n70L^O@-FnECQvAZJ@%sOTkylVG@hM|*Mpy8QpL0P*sQ8Nrs6Dk8JlPpXVJ$* z_e(5V>b{!vw2-}y)2VrH@{V^78{+(i8X`UhZ;egHoEtw3db@fN?&~M z38Va_!Ce#z!_sX>0W*WG{}V8~{h2?SC~=Z!XSSBg-^wkt&GfOuBOP-a@2h~@-W>1d z53)2bN?RRkAfN72h?yDdH;#D#e$Nr`l9FcQl=fraVxf>W{-3u+Eh1Sfi~6c7!}c$x z>Fs?h6I3{JdYn#bE@qt$hqaY9SJf=_M4uLN3)BtfMnyzO+@4M0TB~rSp0xVo+i)aY zqtsKS!|JmeDtMhAZos|Mp|~her=MK1E?sHU6HjrLF2Dm6rax*zIQkl^dWy$?<*FnR zb0wZiVK%-|;q%BeYeZ8{e8w~VtIqRq>;?B-Yj4W;qk6*9)uMl$-d$P!t@OQD%@-jh z&rJrx8cOM3(@G_`sY9wk`XF2KTIY_mR`x_2^P7zl=MfGJ+5*lf%g=}D+NI84I-(CV zt6dAfeZ-4@^XgUokF~DUl6?AmZ6@jneLRSoU?H|M4HxbaTvZka);nS<8@&~en(q$g zX4kQ-8K%^$Vk)o7+zInG$<^IYsY3~<0$i@jbfy~AWhgTlzzG0r5BPDGy5glvQ--gnZJZ)%hR@{Fx`Vn#dpk4x8P}R1- zRxmy{Y%>7qYb#kbX^lU#n=;Hl*qv3JYkXvQYyMY*tFf)g?g8BrXNCIizv*5SpnIuG z?!QZ{qIQaYfbv!3f{9F=+)!ik6YY27Kg+~5u$W@GZMVf2=_+GKz zf&wfNuTeb4+tHd9n`woYPUoo?4QbqMcyWE7;+n!V20d2L_m3;&7z+)>!?eDxmtbyEL3_8VTi5snDIx{OjfkW4}I zMlPTL{nyRaA z9Yh^9)FNN!KlH$i)ysdmVsD!y$3&0(&t>29#cvCv?rOF$vN(#q^3wu8sv8P{saj+M z*C91|*vuRLM?9x|Z3UBteBCz1Q4J=i$_g2YZq1^}jTDPXB+OpI9}iKu@R5e~Wm_La zFHry7SxLs78?&SGhESbP_IJm(EQ4s2vTi^DLzHdhttCqBGqtEczd5KGB9~ARXzb%v zKL`J}u+T%hiLf_o=@o3CNzt}UrAw3GC>)8LAyas#5&tMo2eBa$a)6i6j(?{8 z7gq)V2vd4~Z&z)s`Ue45;4em`5(_!nl2&gFb#4=Ps|49sYv-!*WzU5Ms@Q#9A zq38^rwnN^E@`qFo*3J()QGRn{U&~S|^DjrM^2rCBpx#h?+O>}w=Bu7%56nu&crF`I z)O0S<2ju=A6v33gObGtKy4ILbd~Z6GlXOef+xxUCAOUZI4RU{>-A^b&E8u@Ju>W^t z*Z=a#ZjX8Yxg)I_Mzp<{!$e&OASb1a_yjlh`_C63hCfh7rB?$0_ZtPO*1ukWurznH zbZ~JH;Bhy1l#}~{hU#Si4gl>78UW>N2E0XW=wE;U6v5`N0Q|SK&)?~0bO6Bj?=&^4 zqTd(1zw5Wd{r@f9{&yXe?E=v8cbWv%p8LSuwd{bQ{70cGK*HTEVgUbzlB%qVrV4<# zr`-v?35^N>K_eo zGa&H?VEE*r!RhiPd0>CU8xTzx44esulKifQhG-d>V1I!Dc|_A=vq?${z%~p>KpTho zc!<^u9jT&spfp3Dv4m*(l1~u7RFE36MRbUkCTJePw=(wIY0qwV!NP`F8nYDu0RlOa z5#zp``ecu11t)qq7oi;Bk}Ooq(Al|!iPTM92l>7lf_i%!+W}Aj9{^+wkOBvIBubNY zDfKTurek*9MQbf`*V$9~3Y618qpkPO=6t6k2 zAb@?I-Li#5Q1<2$Qu|Y;ytl6idGkA$+NxtU_S@!uwXGh(!~C%-*$v8>sba}wGeC}; z%{S3Ax|iAHuc|SUr$MEm(PTo?p-oc zK|Ek9U`vQ-G!!BP7%&un#n#xQq+M?7e+l_&X}}-~eL4=!($e{eK_|~R%Td!ngSdkJ z;|BEWbjH3g!Xcm>lHaVS-A(2BPR>N0a9Ew-bmgyz;4*JeC`cS{9(L#FM;dwT0|OYc zHsWk)Z*4izep|;LxWvK*ksVp0y;nY;P30A9(fXO+#?fm=$TYhaWZamtVS((9qUCzNzw%Dg=}Fb&$DMX> zPt#iVIi1Ai+{yDRI1*m1fVmQkeuJsb!=e_R&)u-JxWBW_{4q7U6%;i0lU}A`TK>CE zYw=QvMkC|LF@cT!Cs17im(9BKPHRc^;{;ZTlVbi)t{hyZg>H2%P@U0v-))JkPB5A# z>qDWZ@WKhF;WWv@UNt{6KPn#-O$ChxC0yBSDmK*a_@8p3zDUsiuQcE}C>B%z$^|_G zE9#t>6bOSskU!WU!iN|>VH7u;DeCUQHQbRzoh+TyNJ@}Bu`syo62|LqYV71Bp4sOE zmqLbl=uA8&S$tC%8^bz;gTy zY@wY(bK5zrsD;?%ay`s%d~wZJg!Kc#b6bF5$X>0&Oo0W^?{e(c&bio$@FVp^AAuDg z{+`_%%JKpP06&%EyHpioAfm?f%~U@O)XM;Zf#COpI0n`{FUE}GKSYE4OF}dZoPGiCl8r`Iv+4S7leH8p+!MY!x%Q>i=7EAT9!>JZF7}O9ry^!7*l*5b;G}I7W#O+gi`snk6qRLU$;Go*~ z28al&g3kf?pnhf#9T^(MLylDIvkodC;cJ-kcK0$3n?;A5G4#s<$tC zD8$@^C^3L8Zqg#N#;!)36CDjZ9JsY(g>N`ZV7;(dUZ*S$ima4J2LeLCInp4d^HyIn zN!=-r9vZmR2YX_g&yrKs9Zouy;CGL{r+-B_GRTDGNDqE+p)o&v+mnL;XP$asif2_f zWmZ-dq+0iu-wrTe%_XB3W=66Hf?ZAMH+y}uaeTNZcf{~HUedVImX6jydmq=YUg*_* zOFjOi9>Lz~QTJ*_(*#%PW=a>k^;3gZqSB9by18XWlp5Q4X5Q5iJwGKDvF2dgZ>d=J zF4A1uPU|Uq1INrM!yobY@z-qcIYT%zh2-B+=ZycsA#|}^A2(Pc3-s|p`U%>y9w#DO zMs%}|sA%YtAwPpy6j2gF~&6S&|ed}<}z$@8-@F<*9p@d^%r!hKI z*e96qlmzrw7;u-e+2qUV=|s+Of662xpurVEJT+WD7(OIsC+A9gEtl7Fbcs)YX`%lo zqMP->pW-i4Pc-NBl=>JJq*k@Y9kKB3 zTlccPV$&#NC#nzRig9w}3N}=z9}P~|#N*sex2I1?Ucy5U?Wm>O7q>qlbqnxV*U@=#XJURwW9kg~h+(H;5Hy_UxFxzy)xN2N($6aQc{ML~^Ahv2@u;lh9aL3% z9OHgI74-V>kq7+cyReMQR+F!d8Dxz&(a8^UlyzpOe{BT=Fx&M9vx|k(HkQ`qB<-xvmQ>dCKGW~-+Ib0AZEHV7 z%(!1G%(9tBqyo0*dWstdS<@*$keBLfjc%Gzu(V?|Q~c>qJA4`T#|eDy-ph)=C&Od-Zx0iE$+i&_RvIx~9ns0m~LE_TK; zqgMxQ^9*{GzKxgAH#_FGa`Yt1+Ig}nY=;VLeZev{tlyJNdG^{$<@#8q(1rAqjw*H3 zBQk}W#$(EUeTpN`5HORN)23+CF10S_Paq;}__K0;RC%QE^)a-B+*aYaO~u5s{XK5) zw)kxltCLh4G9bUyz@L_Bot>p$TiQ2Yf46-&Na+6jLf?qu$gprmx;i|f@%rw9gn2K~ zJR6&hl^SVGN*-}s@Srb+(O0aknwfHr%_{fa(CBqT#7^0I%iQX7}GBp8F7R08d zKcN?DndxosK%0kDLxYC79dPLM;f)^S$qzSwM|GTJ`8GmMiIA8b;0>;e_rF_^SR5xG z@d&WH{T-vLI7iV4G{huZgOZZ2KEGN; z`+_5kzb8Do?>rsaB;P*?j#(YLZ8S`|2b$?Bem$hb0O&HotzBR@H_t zzKnX_IzX#%^rr6c*Pri&8fvFc1E^TEM3Ww0%c>M3^jI?@^0x$|YK#3dX#JoO9qhHT zUK(xsigMVdyTE50^$~Gf=cxhSXY?j~h3KU@TG7d^A;dE0gASd1W&6Ln^`^?+S7A_( zQNO!Rl<45^Lo!(G79>S*c?XbpXS-99MH=ETt>RamfTT>~J%*Up(;7{hT0<; zO_SW8vM(M$1-cYSlpG@Y-?TbWZsP9XJrxWJt}+si26n!u40|yiYWn?F zgKU3JXKvpjG=H~f{mF@|bBuFM8WkMM zod;ZxYxs=GbOV+ituy9ySV;!BhT8{J1g2j_p^wZO>q&UnnA+$(IU+ZK7j|{M1rdG5 zb4;fpQt*j%Mq5ZkeOY=+phtYh59}L_K?dT3g*r>}K>Hz#K_GnpXt_WrsX1M$B0nGv zvbB{R4P3bYV*`|;)y@CPu(06!a6)zv+0j`2PhxocG0geRyC7V^)Hj5f9bCmEU*S+A6JW=g`t!arF|hVA0t+bd^$(beB-Jd%`OF3mebHkLo`=>S zS601bTZ^Yb??%*`6CvoA0L01umiC(fzK22CZ`HGfT96F!T&dPS$lejTvF6mLN~PuL z95VN*9S~xJh*H0m6FeLEsXUT*cu~DL%J$`oo5s)}@oeRH>%8J;1_)=%i;a~lCTNzA zF>g?xA0BO{^@pi1mxM-6b8!peYh_wPE9(Utu}a-5OvNlT_0+7l5>64By5p_q;+2s6 z5A*}l`|}lUAur!n5;qSCgtpN>Q_9;H2$1Lx&%y7eVm8@kPJDtB_g08n`8~X;*1lj# zUBpg!#XY5Jq53A`@$BJk3Co9lukS;bbH8pr3PhgIEnSXL($aV|R#o~Q{Q+?iW1*99 zXPbGxzh06qaeg~gE}K(#EKhN$YqsSHAzIxy^E&M5WSn~|$Zu@k!6?>r2f%4)pRraU zOf7%KlGJqgnZ3JikzHqoED?WWHd#6SYN_Ycu4!${Mr##2HlhB5_^N=JjSKU6M7D{Q zWXSB;>_{wW{C55Ho>=B0zy09n2bNDnzLJO-)`%`V2`R4AJT;ta%9Xq8p6JDeqHhEm zJQRoED7P8T+~lA>up%?f8R6?=yj;nP9~m(R5=RF;l>VgV8bV@d@LrObAEC(l@qiVq zj%nJGBjvl5X1u06yabAb5UvX*D9VO_2;|qvEI%=ui*opI1g1?dY7zQ}tV&;m$jQsW zY+E$3FD3c7d8wuGdnM5%xK^&T6V5u4cZ~&PhO}@fzEc}fjwCXxK#hI3L+InDPlrfP zaTcnF**4y)c)b&uJZQam86V$YozE`nUlNwjoMv4<9Vt7@1Qc&N?zuI-Ys%5I*;*bI z7ZT)9b=ygba4OFgs59e;i!8`6lu9L0|K82Z+(GypnvNydr9VdO?X!LEmA*29-aB78 zzp!DH^KF3gID@n(pEM@=i{drZvE`GcsVgZDxW(7?cBi9)_Q$KE-tN_;lZY`&5RTub z&M0=Ga`6HgL8!jgVf}f*CXV)?=~;YcFM*SU60*!@#4FG*B8?{L%J!+1#)?JQkt6Ii zThX7h--<+y8Ry|@aW0-hg>?yM5r?jQ3G`etKYI3!ehXJH|46l2XN~t-%_#g}Gtf#T zqCK)$=Zf$?Vk%hn%XCmAY=6%EyaxPC5qHp_gB z^jT#{s@8lF2EZ0xOFjl@?60NRi zT9q_Zs0W9){6i1*I#K3)6F87M8W)}V-8j3HXUmk9uktoIuc@bIY}&lNtg6ip-HFrD zFBs-(K_+#vrQZ19j{oe!#dCpgCH!!NaWHD^cthV4;%TI?Vwy-HUNpo>;?YN z&6x(m`}r07Baa6}^s+f>LBMdBh;kg7&0t_~922hc`NSPHX3WEPKw9J%L_0L~BVO#7 zY|q~G77U2!v_&lcRN~b78s{~`o%7u#E|yQ?2b%Q7rc9NUMN`Y&Pc^Zrr%!)8;vU#9 ziyP$ZziG^A%{PBBn<&2*#bR?%@jC3)mhRnoX1wl!jkEX6ro%czu8`T0ahsg08I2Ij zaeSM;duvU|UYoAHFp{t;RbVtD%*ZzABt~DC_J~>T=gC4vRoo@;_46!4>=sejns43I zhx7Ns#3Km9}RhLs}e#Ah*!GrGa?0JWqH7(mm0wvfAGK zv8wvbHF3%A159>|3o~%1UN%=!8V>&zXQpbPZaJs1dacsgS{vr9nl$E}xG5a6-#Xdc z()=pRr{Uv=caKl_rH7^B)a2f9UMsw5oT3=d+&Li?WS-NF%aq8Ep73Dz$1xYo44}&9 z3Kb8aMpkonAmF<6S=s*;<>8pW^^0Z+{)GuqApVXEO=OxT^W|s8jkTkt^p{na!vQ9Q zrULzC1!Ff^-$u^hnlPy57O+>ge7De(s*>(G$j|>B%*UQ5PdxSNH*PNzBS_}hUzU6K zC;{%v&j=r$+>)?Ojj7RdZP2?hxjT~B*xh5ut-WimVg6M)3K?NeJEk`_G=>IFe5S@! zZ`^0!lD~qJ1S`Lpd_H=^bQqNwZXnbwav72{P!&xY@LkZ~VM_QswBq&3;7>&`8nOLN zLJ3};ycNdmUX3kCE>0}{RWv54$mQy^)$Au`AvEw5^r?n1@EqV-rDL$I&847 zp+1wWLvZZRbcqB%ZaMgD=8_E0pA;Y320OVxm28BC-n^4xua(oD-p-ga)a9lB5^blX zCySwNJuvx_zx?%O{Ysp}v(cz;n)($%pJ%;!B6bXp<0Q3Hzo|^W^L}7B9Jv18m-gA|nIR z<94#8oVCJX36|YnwKDSLyes=7#dB0xw>{RI1_7 z|4awcb!BhzMC(n#u~`*IM4AhKL7B^d2=m-!h*9;PQ27Z7xx`&|$nz50(}|a6Y|fz( zCL&}b-BdN7Kmsov&fsVRAFR9g3^#?lN1W`!x1TSD zCGo$pudMrO4AG%_wGU!rPdWYY;tyi-0SG*Dwv^OoR3XXe^C0y>-E6qZXvjwcIW2%Z zUuFP;55Jp^ZwY94`CEll@QHX#ZSwp)%y8?KZew(#;`}8vJYC!3a~MI79sakBsMFY& zw6d@8u7{%Ii=TY&?o|qxXMUvq>U;QrC%^KDTs2$BV$*<4$fv^RPUc?*F7t$;4 zNi7FLF2~e&W0>m~J43Vdvz*Yi2EE%k^mJ!e_8sAzmxjIaF)H?jneRBS1%PY>`E(8< zb_p-PHLRNV7mpc@HY6{oaP%1sHTRAUc)$PHkd`Ur?bVWFN|;Qk^MnmVtU1fZz;zTS z9dLMed(d>(yn2DQ*MaComi%_;+4CbnQa;}7t`0nCiOBCn1L9(FTwFiX`Iutt<3h;8 zWrm(Pe4N?P#^EL-OE#4BmQ9aYXYNbnU7@~v+)JSPxGmSIUU^B$ml!GA<#^4iuirA{ ztKMpP4ySHPL22W^+TBvsX;kIqynJLPxoUpB1{{_zD#`3*Ht0*C{Ic%xv?n8udX`=yTsY1G&wa-;7aKx=; z^N*)crgf1flKE`WnC8e_HX_8^2e)t6fYmRj#eS~s(iF<*=t z?A?yNHEga@+t#Pymfe#MoF^kKEmf9xcLI?%@>~i_xZRXqWu`dC0nkOMavyT^kh}9mQhO`lzbdaZF#G!r4^&~UqKVqL8xU2{_g_> zP7E{#hyZ0Fq0+=2odDiI5JL_q3)&5iLGqelQb{78qtB5PC(phs#i0V*aDaO{fW7JD z%z`Abm-?St1^U)P@jtVa;g$5dYmttG)M2Qbuw39uxBt~55u}=JrS!rYl{7_ER0I%) zaTvV+xxz!%gApIXD-|6r#c?Ug3r0L|KgsgJD!}%jduW2uZn}>4=Z$#xkxf)!0k-E) z8K2jIBN3z|Tt*kA4Wq06udtn)8(wD~)tXB9>;xtzZ2A0ktN)Bd1WhRV8Fj~z2$%p1 zl~rswzj+P;zZ%Mw@OMDNlVQ8NyPFS<4HhNo){KX>Co<;c5CW^n8g_qQ zF6q$wd`|R#6J@t2GD%6Issv!8>qOuZ0;2%Ol*g);$-*Ivl(@X;6hEvx@g4ElzpzRA zh04?Abgnt|su6PWhk-UB{XG1j%`Ycpmf4*Mn92Id`U(8^4G}eA#ZTE zXb1i#+ExIwA7U8n81ICK%ndeRp@XlpZ&2=nak&^yX*h7s4(MZFz~!&B8I;m=qDpEBV63-AV%L1zQ%%XNO#YtxQw-(^YfLr`0<#*+b zIA-^nv=P$!RmUMka7!3FqB4*e^;=URazKD}6Wk5BJZ}OrBECg8VAjNOcno!7qr7N9 zr&>1;NhE`|iEHx9SCqN|r&^>r`82kQ9+eL;tX@)=m6N&%jJTm{IPF#*akK&RmAuS! z18%4lD_HfgV+o`(6DT9;1XYU*J14$BK0*3n`l4?uzx2NJedmii&K@MiD(<45dsFXf zeUKtynei4x2ezdHTQWqWJiH2^M9P`1r#V)(3B@$bQ9vS)ILb#@iNFJKj)fud1EX?A z%D>|eo(O_WPp3Fur2!xaFf_qPJsSvS_fZq$Vt%~24n&>_zKojLU+rW%U^HMjfAL@z zgf9%%VYJnmhw}PLLy#{UQ$DDGq-`0JVHHsg-JX>J9aw&l5Hvr$IMOzc_kV;H>2N__ zU|D*wA|oA;h!hR|&bNEF@mO+Ahtr;z%+`aU@(Tv~4FP5bdnXXNSy}(*4Jm1p zX2|opy!uxmKE6^7%@sRuzp14@J*vA!LvL!*EP9Wd1x$uRg4g_v87e&_oi2bys&cINsykBoEhP0vA*zwp;rLsP_bsQdKMTBqQ;m} zn4|r+v-h3MMP&%Dk1-_pIAE@7%|{y?aX||bXF&{wyiR%h%lm^NP6f~p^RF0Ktey{_ z(=O;_>FLBl3bq@FQ&@u8yc=PRdM6H7jOHaN^lI@2)-%>_+#B5hIRL34j#6;}x6&?% z7+~PTKTBNq67^7KohV{47Kv-11(y(!wVQJI5C0u;cBo?z8{$S&g&u4AbieS+!(#kG z4&ftTD@F^hz?8+8^5B4){W*~4M6%^q`c|fnHU>mD<2ejo6 z?gH(eA;41pAohMi7>Il=CqK#S`|)wGytqjB;qy>tN8hmUoIs#zu%P1_W2UaNyh9R` zMKzxMGlwLnwTWmC1KB|?LFvNn{`})l{A&-xw@US!X`Ec(DnUPTn17M*;y?g&0QA3I zkoRI?MJQH9!-M_1Is;*ntBBWBf4DKwCbG`RKm;Tqz^t`n6^cg)74f9wsN&sP##9Lq zCJP7?!~!Bm(|erMcNyCT%{u-~#wBj+7?W#u4puCxm1lTTF0FP79#!plimAjbejf2a zKB8&`jH4nG7Vp46qoiWQ>_hg`{daUn+M_v@F7|L=v*Af70GP5I3?!RHkuv_#-E~;sx5fTQ+feZRlwFi!e7|YTShyn>Kb-76SSVi}lAXdpWC^ml@ zKvy{=fjM~(Rh}TnH-$)ETb2Wom=MgHKn%uZX9QO&pnqQ-jr1>lVaoBBdQewGjrjji z9a{HFLQ4H!i&*}f(zsU(q5oSHgwhh^guqHAT%so`A8&z2KmcJ#ZAw0UPyi9guWR$z zKy_l-mQ~KKzC*x~n2^^mJXfkacmoo%ZnAuu-VlHJ*==R(un>{B$F@{M759ANYj@Ew|5Ew~GL5=-INA~0EbSRL$ay^Il zazaY#@_1Jmf8$;cMbd-Mq(@@bB|F(C;x#D>t~?QHCplgOza|*TOz~mSO4L$BI1)!N zuxuy~ACPyD>EpzmC(q8efb>{7Y{_>rhNlw^eBUg7NHhq#F^Hx2bvrRhhf?`*O;tK( zpO~0*ZETivlW>WPh3Dm=E!Rqui5i$wG2|#_UN`4<%kFYXJlU#LN;2yuaSNs4^@lNn z-@iLQF)n!~5Qcw@AW@cEgKdF;5xF-O^c1m0;*X8v%n<#`8{v$^U@2mxQ?jfdNJ56l zYYD6dG~f*i_5(XkB*WFk)5wMd^-pZI{1FIF~U|6uIY^m3SA*84b7%mMaj+Q;{ zrKidzGY9W%g7VBlbDq$MGov21p_z{)@(NzX=3m{iV(*<+c~3@MjNZew8T$H=fElCw)kNXB$b2jW?Cslk@gxzct&#?c~b!+@dkU z(0JIi>@Yvbe@8axfj}k@7Y+R*4lzQOpRiI#k^H9N;RCEFSSJ@5zdM}?5x7&d(ia!? z#6JrLhi&y}Oo6z}!N^`UBnkCTQ~Y`yTH_Ltt%DEUf=*9tkm9DGZ?%@kgRD__{r1G* zbrTah1a-FwO&G{O4@??3LMr5UHK@WI)V)f2yc$XxQ?n1c>+q5Gxy@A?%W-n0le1hI zB%n>@ctC1dgS9Xg2xEdYA{pOdDRt4a%f`eHJfxt;RAy6FsFh9I&-6%V^OtVVfLF^oY$1lJ1nWPLtLL%MFA;f^?sH9Yfbk!T_m z7GH7s+F3V-n@yxeflInbV|ts)TsrjoTxU2SpvS_KmOEZ{k;R_tg5rG+TNDuhM716F%$Cei^RIj6Qd@HUpji@zEjH_Ix)`sSuT)D$Qu<`5X*RUp<&!vZGAWi#rLky1wTl(&)v1J_4N0R zSo2>-8F|g8N7l{M0dT3v4BV}mxCLn&bEH<2k z(tIGZyLTzUJb}FV$$A>&kLHGvI(kb98`>j{UsIZzW>yT0VXnijt8#h^D8GnzQ|+zP zP&5vJc~|gQ2WQp$iM%{hIXBysP=S3K}4jJ0FDU< zmgRGdQ72g;3z1pu(4zPn_~PBzi;k>^ne-S55)y4kU~4c9m?(Ts+ufx!HTAj^-oX|S zRBOT$G00Qplrr~8dc{5UbHSoRiW5-aS-Sk<6zAT+qOdH3FWW;Wy?}8VlYb6*mDR&Nj{&>GV^=!(?7!XFlddEy4?9#}XQWHksh& zs&e2+`|$V@#2@*tpPCS65$%eBLA^j4JpCeAlP`W1Iz4aAi0+dk4Wo;z7O{R9%U?o9V0l*6U&%OaTW&NX)5&^$nm+AW%p8os1eW!F}4k9FR-h8{9l!ewd zw(033!A$^*=1KDOPj0q|IhC((_5_a@o%2a-Wn=1b>Qf&Tp{!7kS>Bn~DrMTj>o#o@ zU(Tl5JV<<;p{0ZsT5H7}qoZexS_E8OZfWBA>04s@Ouom+ND|gT;gD-x;_DF@X`g-m z4J6eiG1R)mD$9hb#|JG>V2dKfzM!H5Gke&>KbYMIK?8#HLw&;W!hnEFEP#K97D)z0 z@NOv5?}p$Pu`n&wm`sN!iyH=zvm3a_NqcnSA}MKvhXgd$hy_J7`6XS(mjDfXJX4(e@ZcS57HVP-DtO6=+%hiIy`d{^Kx zbvjF#%t6KWOx?K}syeO_ob>_OwHdc>oTMTno;S)WNILtc?FC>RUyCBaofP;^AOX@> zFC7FoY@^6ha|2pWnTz{XbB&|7F#71!^PE4ljmCbH|LSgU_-XnNd^x-MT4Q9pm?Wl0c>s`n!ICIu{8Jj6QtsD|@zQmK0-1^( z&qz@3yk^T`n-3ZqWN)zse?(vpIzjhIabqABMCMw;%q#-Hr+Hw4aSu6pl3D4=c<&Px zC$=W%ZQLDsyeVF+=wDu_w%-R#WI(tB%YObqPlJQp2a&Xx;2%f~5Zljo=O=lGU;kk1 zci=_qaG-e$HXpx-ft;zUrY7hGhHL5#o}RhV5tV43SXQtWMdyxqYFP zj{~7*L??qSOqzei+O_PZK1ON}d1WEm8+ruIPp^xPhjW7y!7nG>1v^dqnaN;aHJPSt4(ga_QNJ}` z@#+^(%P(F$-BF%wf;6VwOq99IEmMj){zKHcZVT;LR*i_vsYLv-XdMgEVG;Dw;!T*1qL2kCZ~Aw z9M|008rZC;T&0*W!@)=f5D>tvv?pWHziL(VjfMiJUyr^wTMn)Ey%8|x*rBMOESj4M zAd33r17`Mj<|bU%x|iQ5C6enDo#}OpY@THuD4pQ-lY?k8xmj{>xdH``BScGLdx|r9=qtI#AMy!X-Im%ax1LPZGLfPAnuJFoZJS|fDH484MT{5 z=wJXu_&V&ia?*E_B%Hp#+02H0*uK|)0<%30=ElSN#FSW#m;s1Y>#u6(2LRKWV9uwX z*XHYlcI{a<IV&&b;z0D%EX0N#rrMcLNyu&l_^h6^#zH)h>&(Y=CY8!D(Io5@oqlX!5dx&AZs_wUa$FF z;|b*7?zkvTOgmMPrheLfb>=)7onoLQx4U4TGSNCtvvl9ozX|X39`H9DU<9lcO6{!n z7h4^TmMNNQb*V`sm?Z27GUVeo2R4PNT|6vShRIS&hsKQ@)IJFH51gKJB))s{_%zT$C1Ct{awQ!eZvY;I)O96n_2ShMTEAN#MF(y3M&qNJt3HHN( zxBpX=LI%BmO_vVW+6I?F8X$K?!Akgi-*JP^xTxs449s*jU;UF>IvkHs;;}GW`X(e& z)IjIGR~YQYgtcDVL*hpQZNSs$_hCQZ3fj7Gi3^j8RG3JPTTU>K97FsCI{LE~$Y>e; z%~dVrD=Xid29r}U2<{?D56(kKL}g>fWhbgj66D_g38CQcHVUfetJklGXlA#?z!F5C zR=|0OnecU(R-ad@bp}ypGFp<0c#L^TVQKnFhw>vVh4KBR-bv7L@q_v{q~+?3qLVjr z<*xgPv7G44K(L&^i4$R3V19X4kA`DiUn-?`!0DMpsm+G>3YViS#Zbb&p{JOi`mmhgok?Br~3Uwu5nBb;tbW(b6cvm zp#(9oYIgp7oelO;b`KeUNWY+E_R=VTG2A34kavO%3MpY*`kuh;-MfD zj5{XN`41hp$!<2kt|6@RXIMuUn}hMeU8tarokRc`O3tr8+4;+H>9_<{FDE*SV!ovN zZ$NTiGg|04QJE2e{CU@%sPw%40F9Ag;^Z*)5`C;eR+Xy$mol>7N(&ts(j3)#q2M^J;I8lO$53 zMCiG%TQm-P!8SzV%XrhOJ6}cn1n9+&=1A9N@ri+YyIy-*kX=45g(opzVRpazVZ;?xI6iDI0&F`lk zW3^9T8LyxMfTvF7+UMgmiw1tr1hQ(%GO{_YEjf`{)o?L65ok|@J(MPV0%X)Lx z&$cXHD}1W6aqwioKUq~RnYxW%?lEE?O-fQoHeK9nZqK38mKTB!b)WZaYgUB@l}}e) zR*#WX zZbHrIqUR!u&^a`$4fiA=iH$k(S*Y()a?zGKTp1r!ohnl&R?dy zbW#3`jWDC*kqB<%nI3oO04?qpeZIu}z!D%GT#F=jmDlnGLby0K1dfdvke7|li%)G8|Y^B>p5$l`=bN&Yx#Li5GQ zV$IXwkbj=3EV9p9D8@k$_U7ha$M2#xu+_zuz(*wv69{Mn15X zA*~~5c`Cot{Ag3Zs4m=U{ng>@qx|cR_^K^DFK{$lYo|OCe5tPZ^~kV}v5rw&)&h42 z5<%8y+)QfY5qW$22q$O4s$-q$2kVLXx@gSnG(PeZU5LU>blSdTsshv(u{=Z3CKi9B z)G1X(NvzY?A#0lRfu{WJi-O}o4`z}G!m`g_-AXL9_*dKND&UUr_N2jg3i{s4LE#L? zMM(mBCva}l+04`}OF<#)u^I`R9x6H58=&1n2;-+_Qh!KNB25|pDVD3q9(R;rsi#X; z=#jv7Do5dV?P+&@ez@8jg5GC4dsvy(& zCYp1d8rl+x_+9?eq`B&<1wFpuvc65@MF-!eT2L;^8oY_jvbuDkMr)~+kt~PuhTKv>CjFd~Z_Hjn2$9LQb zx;ri0e|FJozFkzyfsavai*ua{$q8yASFC3)9=I3EbeDoKSidYppZv88JT!n z!4b2?&H4gIw@5Cdc}n+7!E9%4DASjsh7xg>kM`Dx)CO{U`!CV;NKG3J#R`{ehN`>_ zQMt*eP5PMdB6}RdZ(^w=h)vLEa@!TCqjc$Il@W!Lu8CGZ7vsy17U)?6e`p9f*!CGV zUs`c)i%mCwd>|IL@I8o9u`;-FIOA03;w@=cCjCuyfnE(;9V2UKY`{0u9)5~tX1~oR z$M!5#ic@p8A4q;Tr!Q9VNaSIW%JUF&RXH21bcg1ahz%C(Nps_(HRlx@wU})em&RI? z$R$DImeE@`h&&$v9(Ao*p{qo*wgm9CBDdqa=zJ-j1%=Qq33r7MAjZxDg|Xb-rNSaT zE@pY6s3o;0)Y@rEq-I)0YP4M9tC)=3t#;nPOd~oA4Zlpi^h__KIIpL~%uzE#EUHyF zR#u1AF+`LLcg2S*15oxr~Zg6$IvP?y-2WgbGoHDvb;p%y&_F?+{|BJP^fQqA8 z*G6X;Wbk2dAKWEaNPuJ*+$A_9xVr{|WPril-3d-`mjD5R1`P=iBtVc5T!JLwPQEQ? zpMCcKpL^H3wN_VGz4ca2b#--hP1o~2<;U>w%|0#~`^7!B|81WULw;;k76)&iN~_rW z6Gd|hXK8VU$?I3TW)%slX*T|{uAyv>lJn8(T9F-izkCeYcdPboD-~c~o!) zv#aHo(G5B2((B0VnVjH-SnrzK5uB3p)l(CQe+;LS4(mDYyBAh)F31$@mVloU!_Q}} zgilCa*2~>|P{bo?|7M1gzMpHxzOQk9Fklk%RqaBHYc=~u`v9#zQF!OW!!Ne6Bx*)B zTk&7mM5TBsnv+X=H(BsKrGQT0k#u92~ zo9i4FdkntPVY9@_iCr^&{5yhVV0MA7O*KI!yV81B=1?w-ATd^C7{tm#=;}vu?=aL* z*1UF(3#F$;<>;3=zL3Oi5zUEV*VppR0j<*1n1sT*8>F;tM zjVy1(k_?q)8bcJjnAi6`(2^B04ifs2vyw(f&S22CbftLLv|Ew>-T~p7=hXpp3{Xqq z66KmAP@j`|!ecrWeO<|9&r;vQaT?%y6XCLh}8H8@r|b`#1&)u_F*M{5#9(|)+> zf0Zhkof65FJeA-wc7gru`@l9&ovLJKFhW=Z*LL5cUHW}P*x6h)dz@q^?8+%ISNipS ze(3ulOGhz9X+TW0%=%0bZbV^`UBku%B*z7ktLUqE^$VXCZJ^1jin?Z!uv{e7*X4x^ zZ@z__i(SF*!NQjoj(K6qeCrX_eeOlaX!vi9Jm? zTXkLPD604IM{8zB%wjG3)UW2Z+(T9^7<;1gRHe%KC~W-!T2%Pi%aY;nxP;xLO=G^F zsw#5bCRt6kNU?%|&s~p9OkkSnDrR&6gS`A5#pi#iG4PbmsPD28<5 zr56{|ClenCMWv1vvGZv*h6`@pg5?K)G;Se-exBP^gE@M#Bv&^k>@ST5@EMw(70Vyx z@wHtj~g`@^1&afiOv4jWLdUos9hsV$s62-K`t|4zVMAN z7@rMVK&JtlhXsnbg+s=H>W;6Diyb3ph4?^NacwaMnfC$r1c_-L$$;6vv4VN$nTRNo zX)sAgi5X~sF_<{u9Ja}sLa-|-hT96*2^-E1nR7$Ki2!chW+F@w%-J;3izyE3U4>Gl z4<%UfNPy$72(htZE?9O<rQGk~Vg*|2wlKuR!uETKO zw+~C3alRggJRJwIF&M?Vvkl%lJ+b`AnmTzg;|#q!bE8Y$gC%=MjYiFg*HmuW;+i_9 zy+h2l?Mao8su*~?U$=WYy9b#wrHR?9-bg2!$PDvnRFadowz{kzIa z$#Tc(O8`QM*}S~#h@3#E@MpggW<7*UD3Ex{h~8Hdp=Ejfx>~zuVD>}^;an8hm67^!cU{eh)%vc1!&_U{mxb@lhBJ;tjA+bL`>40US&aSXE@QkoxLr&bz4` zMH4Wl9qF%6(w1KUt&boEFhg^2Cd5vS+qQeFf<;_)8AS``hq$W0@f+x;_-c3@f`<9| zG$tZY?c^DVWm5MLFzd z2{R6pr!6XG_jArGD%(4KW+6k9Dxt8;j}udWx}N(^pY$LTpwn3m;+eIM%GO$J)U36>zjejfR#zT!{GLL@`n}_juTsVE&`AU-zT%fkaacV8EE7@tNxJFIvd`lgR-bu{7c4#- z(;fp>gn{Ioe$oxZ<@f89g0c^OmEE0J9&2qb`L@LwtW6WjJYyLDojPNK`G9n0sV+_I;Bf8>C+_@A=E4r0oDG>EL+Ynma+J zXG=(A$79k*?546qpGPlyz2hECWJ7T0=jlna1jqZY)l}tAaZ$X!nRT(MtQUnaB1#Y@ z(Mv&Irl$c)DAzhT(-E?*K`y&l5eL;TGD|JOQoSO{WSq>H*JKLDng^NQEd;bnA7R9y z@URxE9&z}>=n0~#NKWIfeQ3ck=1lc&1gZhbizFxrl`U%~S%3gQI?;;vmwVkkX)Xaw zwPDUZGha}w0(FCxZr5pSbRZVWZyBCek$T8~Pc1P1T=8-X;=`oTM_K&xM@we2U}WNK zlrR%nWa83l@v}tgXc{%ZgywP<|Hk`x;KBa#KJ#FHDR8eBf`T#V<|;&WWKjdh$+B8) zPCDgq6O5*jBLsC^o`f}-^nh?s=Nnr)#c<8D_cVU|1^%t(1O>SdP zUoDfOiUSsRuK07lYWU#T%`D|GbUXWpR_7>piPoZ|Mo_r^jyCnhJ8}i@`IM&--AM7t zvQD`(am8y-Pv!C}4^PfvdTot<-%spYuWa@>GBSyvmGO=w_cj#1cNB?d zmnQ^znAhd`Kq)?C_Bw-u2PaQ)ynGd>>+@202y3uD6jlEiRRqZB#W8Tb3=u6}L$hct zBRSTDd^oHJaALq|t)O?4)s>6CFWasH&(3a^8Z+){O8hFEp`F)41;eB_yWvmGQjJ*8 zXFmmv?ms2%$V7O~E(w2p9WS#tKYeV(iWMj+I;5POK}{Qdt77-FHT%gdLSxBB%=BFi z>|@mw^nQTKtJYkmHHD_-!->TujD(jfzxT5*k%c5JTGbT=4!COrvTHuWW1F{EgU*s? zPvl=z`R(wJ^i;4Q=tJJl5Olq+p?E>HNJ^;C>t{;y-3Uebz&{kSOOElVMukmA8YU>K zPFs&!*R28>ym`H4VTyo5L5&k~QDy9Z#<35#q&P(YR*-?580s8~0rt6dQ+Z6vZt0b1 zU`GA7eKD873=r{l zc!R|O{AYpX@4u#t&eiW73lz&LLWigy1;>T-4%MjAfgrv(ag1PgnWev`i;(8{Khs4b z4|b)9HFMzLOCt-j^wY|cET&%k+5dx!B2)tZ4 z?XfIf(S`_g9?u)R)G7JR;q?i<85T_O_}-VWurW((uC#A}V&CcfID_AAMxj;Y;*5bayHMWpPbYSW^mvl7&Q%oroY#zMbtbdIlPIiMs~pbGsl~x)LfbHrTEt9LNg`4#%P$wc-j( z6R#_E`T+<`*(?#jY4LL4Gn3snG3{LL$j};zRV4&w}*3_%lY?z zcg&Fu5%NsbM?WDGeIqDm6Y7|oe2#RepB7710heS4clp+^Uc#S@f^n6}Nj>FhfXZZL z2oy6FPO?_WrWlQ|c?ZQSnp;jNi2_2Jnutb-PDB9%Ge@(mIg6`)c4(V;hIH*4*}>pK z;AK!$QVJte;+GPpw^ko^DWJ2MR^oP};mP(5lWM#k-gN=M-sIpZ}bS z7#}n-OKnnhF8^Ld4f{ELP?(B01sMxh#ZU#N5Xw*1l;~-j^Cbx>&aq}v+~-cvZ()(d zpn)FK1%}X~K+uohzhDH*g)sWRA_flknfX)0!r&)vAz!cuyLs=QY_7v^z-YD_2ECtX zJaoqZ2CEwu4QMX$Y_90&(~)!a-cZ!n(fa&0Cti(=!8$R8a+xXhhz=XD#-fq8mcZ=? z-}=P6kr9=X6lR%z0^d^KS;=2y5ZnyP2oA+bzg9@uJ7#kU+cr~nh+^~NU2KAJeJ0(7 zXpHzRRDcvXMT_;7R$phs-IJt>q2t-=s0VzH3Y%}nG$#srKj-A+M&y2p zY#hU)>xPBgq*IcosRUBwc3bt?cmbFa!NZ4iKf}>_tK;^;{-XLv%bRxzzlHoinEtL2 zHE@QJFa&^v=4~Hs)im%yuadrXA8cBPS{;X88c&(N*gZ)iZgn~?K<>o3+kz>E&s{hC z7d_yQU)G19d;6+kzN@>9Tgbdq!!P|wEtcm~0Zhq!EsQt6E(=f9EAq!~6}^owvagwq zo2v=+Xfqh;6DIE7-gdZQV?3PE3rEXnawgK{AhKj|nMlEVFzoQ~@XT(x<{UL4UGsJ) zW;^to!HgRJ2Mv&Ru&*C`03uDI%2bIGxnh9}(ql^FO)$~Ixf>oo6NB<*alz;fWFc1w z=haWwFiNBwr$g|XTW~wm72FKc{#mB}6X5^{su{9!iK7?9u40u?rb^d3yz=B5 zy1gAAK-J-TG&LfI2999pfT30z3`wN>1(*|bHO)_ol>#O(P)vk3xR;3#(FPC~iq0jo zW5>_qa3CWyWdp0w1X+)RXt9C^H!W?4hS6j-;Hno;Mlc;0CN>n5;j98C?pYhaqKpbn zAf>}cggWWh`c1blVLJrw*^zxEG&i;YpcN5xYaYtE!qbdqv z%7SC7L$}T;%=BvPKXHGLw#zisa-;I^>B@eWX&FiO$Znc6IN|?kp(hm0u{3O>nHgW{p|j-}(T$NJ|LKQnoKdoYQmiiv77qP`OmKVo-E_oNW5n}0%}Yv!&VxfBp{ z&s1H-vkF)Hj`uu+UGs$}o>P9#SHYUT5$_|lXWeTl-{hTEv<?%gFXKm2&ny+CvIC~V}((pyKPvM5UtNBdw}aWDoDbKR`b`E^2L z+*Fxw3|Nxg*Ola+Ig3xDRfj*_sVT|pCm)%g4klc;eor~h%_Ff!Mdj35P7V$Zu!oNn z?+j2B2CHk_FAV9&93Y7!tjFMQ?D{1Rck>l@h`$6AS3SD@7S0sVmL3hQjUS?Ks4O@U z-kfaQ9yt|+uLqlBh7U(X3=Rr}VCDRjRjT!@6*V3h*v?(jc|rBi$e=}fAozWci>jLZ zYu2`SW1;Cxm9cGauu5}M`zsU68!CL`llRUC@mUN06A6KU!^cVy<$D}@L@8}!yJL-Q zLiAI_qLOS-j`}wh?ySoZ9fPgiN4M{4<>dL``zmwCM^Cihls^6XX6NGJ>r=16mgewM z=ld1h56XKn+Sg(eYv>nK^&=?kshXBwL{ANFrJP9&vo3V`yx}7Xwf&*DW32O|PIdt6 z_v0Gicjlu&hL-9NZ-O*vqvaP~&*-F!zCV#jV7Z^+s?WpX5r-8_Ny#e0w&6dxd0U%h za%nT1>7Cr#9Dy6H!L||ay1Y{J<(sn=nq9*rP)7gI+xgdPG9sGzULUDw?j#^=MO37zl z38S4;mP65Zs=2Ode!9^O!uA(kERFk|F=aQ8d@}@!;w~66-IJQ@I^duuTH(8Z} zZ~Eok-8ve~L1!4i-@hbZg78K|JN`I=I2LxQG0DG0{>9e~nHnr*M0T(LO$OZ47$ba# z1VjMtVT7CbS+W-%Y?yVY`zc9n&HGRpVEvMVqzjwG>LWvlF({uVR>X{7m%VKWtl^j8 z&^`Z`V*dos$L|S_A(*jj;=*_T0+{_<`oBeQR@O1hlzwd1!U2l3M0Ha4wT}Ny10AIs zlRf;ytcek3hJoB4fBidAbQtV`xZ5!JnA86AqdF@=18YoIHeHq~2gkk|wL;$i?`a1JwNGo6> z8glj!tT`Ez+$ypy0taUP&nx&#lJ5>><<$RH6aAe40?+~ga)i*7wf_g*|KG&k;cftc zHr0QXhXeqa(C8yL07;6jH!`>ne_LejyYWmcl1QLW9KeLYhKa(0Bmb7cHlz<7AX29p zM|UPT8o^tJc{UyN)lV7pG#ll&5%^PcvU#Hu5YcI6 zOHEQ&RP4}|=q zasI%FM=Jv9t&#uK|6c-_GSwu&X`Fv(F#|}cWC2LLFNy#l90&)Tr#@W%j1L4M>%nk9 zg1iub(vv3sJA!~f_V1kw#D6SUfBaW=>h*d62m+WKhWvVSC9jVBN11;+M~}TRP8z833z=^Iv2`TI=W-gN?j&sYDDQ8unKbmJvk5GZa*L*tatx1ZT$9O6(Oc z?3$0#q?Siqt?vaj_y&*Z&TS=Yya~4K5J?moCPV&}?>~C7euN@@=oDDVxbr^@(*L94 zzX>sF!2tAaxN?6f4dBIcj5X6=|4T#ELaG3)&_fUVH~s%>6bQk%hXJEu`2J5V0%3G# zOZ;q#bOVfN3j!RpKoD$A4ZYQ4fCvB#6adDr9?CB-N|DNmrL+tt0I)E@uAyoH{GQww?@b5XX-^=Bb%Q_rl`ci}z4sr_5lqCD= z!#TU=NA)ALT8$uID$bt&36R`*2?mDP7EG_BGmkfMtX`ClTJXIn>fBzR!!6*7X6zd2ve{SzZ-g{X^;h6AGPA7 z80&v{d4Q-`3Cf}b(c`e&-wsT)(jW6rQ10Ijblz$>0GN?+PbMP&iZ0L70Dw_(io^n7 zpr6eubZvxm3nCek7oR*tq;3@Qd(py1(3HJoXz=$5v+kcuCG&GGh5e~Q((TP(=+8gl z|8gK}5U;sn3R!F7EOR`mz7ix_qF`tS z!1*%NgZZZo;QHVCFwiyqH;31UemDJ_?Ee@Aev0~xbjo*_7fXkS$J;fhY~ zDz!SKm1D^RnU+Z|)-eR1eG{$w07x*1k+Yhbf=~8C(wBaL$}=(s!}y5-Pz{U@-u^5U ziBiIiv80seKVnUGU^iO<~{#o*iur;1NJ=j5rb+dX-e7^chZ@k}u)g;xGmu~plJiySc_9j6hvB;33yYFuf|$%(ud2>@LYU=m^AV-+H` zc3~nS_*4`)!X&>peU(LN>J9qMXT2(8enN>bsDYTsxC&;TLe#X39ZLn4G+r!WzaU&_ zMI|JvYXU5XFJBnkhlK&JhbXh+?Oh{&W3q>kOJf#>OiQo7025$R1ot(wPJsb!I_YDt zV%u;rqzjLI`5uZuQ`s*q1e&>_`RFQ7qg%=$>aV*0!+VLT4`eoD-Uahv62(a479yvo z`9MgdmXoouzc2%+FiaB-LAC2kH1H}+)izxZ?}Hb@rXkG^hyXLP2TV zl4l@Fkst$~w#LJHg&n4{cEuziC|w`&ZZHIdf!v8iSd>J^b(pnvi0=+V-pa;GXHF>Y z^d9HE_n>(YMIDP0kJKVyT?CMS8@l9`fkxJs$X1t)kNEC^-$_341t|ZT3d)(DgqK-~ z7-$w(DfINo*^NqYk?n{x#y>tKfxmx1(!|@Mrf|~b;3&2^6dH&8%%{-Tws*T{oj>X* zzN`}q^td!jWL`SdHj6H-R9?-wJFZK(WJSHwiApKOlJMUyYw=cWDzbhk z#wVsbTHY$-mCb9F%$<`ifoYQePHUbl)lvvfLfWk`eBOgPjU&WmVg+c&5u+;&M%Vh} z4CNS{@Jadr#RJBC&wT^dnn*!F6X7mCV(%g!I1OGgo3OMe%AnVEK}d6mG`^vryYDAi zJl*E$83F^Ce^eCZaT&XX>+~{kFe-a3_XCvwwkC5_9N+LmOL5v<)x^rzhP!8Z86ugp zL@tB50OGkkGY^A?zQJAc3B^<~U{7is;$Mx?#lpIgBXz-NHH2GHQ*3j&b<0M#EE z0NCJxupX)&j?3UUIOu%gwB}Vwd-$!$l6KFg(@x{Foua1ovVxTU&hPS#I~s}fWR|;% zdF8|zUb^(SBU4O5_MpTL0tz;DTw{}n zZUqIySWb>NmI|9s^BF;6QDFvy#mX1f#UOY>Us12m+`F$OJtb^Zs~m$ch_3&zj19u9 zx8mu>T5DC*mL6kiV69p(9{(CMHMT>sA_fQ`Iif#kV$e%w<9gd&@sEiZ{+}L+cA&mL zKEOr!{N|T^Qb>=ok8J&8T*3rj*tB>$8aZQiH;%$c9oZTU#$;#JuwK5bN;w7%lJ;YOT5sD!w-jsFs6+-hD+#E*Ja5^!Faq7@Y zW0ERlN?kv|N-1pgLK|0PXD`1Slztnw`xDCZZ8uw_vM1ibkwB1D(k=<&5*upkG7w9J z>>ogBy(@t=f3Ot&Ase4KuhyWE|As{4D}Cu@L1dX~Nnx^0KPGiP(cf$}@L7V@)Xb0s zFa#Q?owN}y{nl1McIFE+Dn3*`n)dx9w^2v97MXVm^Ru(p}5kJj9N>l zCYqq4N)K&C@s|MrcN*H(0^=3Ik1b7WBQkMc#r7FZx0wMycUi4mbmYqmam5k7^CV-; znWn9@<1gkSPWL&J8X(dM0Z0F0+L7v36wd^nVL`<+kiXx+WgwA{HU9!Z^`Ds5RO)YT zuocM0g}54rQ&NX(F=MjYy(7UHj{3#QjGaQX@)~!!j#}J zb1iw+1u;|$YgtWs*J21Yf*J#8q&S6d%tLFmc*gSwEmdp2L{WFwK!Lm3hEG1=2tu3YKGINd5*0Dcfx)?$s4?iKX+sdf z&8!BzEJc7qJDMe^WBEyMUnC69Bv8o3hp!>RHp?T^Zy|FCfWrv_!9O9KQoG`KC<+wx zM}WxSj+=Cav>BdZVTx%$WnI{*Dhqk|goVp%xxObdZ=G;G0bd4+eGO_6`!cNgJbs6n`&rHt#YLo`&b|iz#{%pSX=u&LNfdm}NH9q+`-8y2 z$0qJ#ts)Z1M;zw%W{F=Xc`n^ysmZl7H6|r4risq23kL3N-o43Q#_cD+`>RaEb(C3a z4=y$Pupi-5%1$?I?VQIo)gl9hIQr>nv&5&I+(IT z^!(RFnCcaM?@<6D6r=?t2)CH<$m3LgA(A>nbKxHg6vg9vK;?@t^VhK;uFto&=AImy zca_>JxRQJ&qWfTxnh#4}Uy=NsXA@5;R|VGc-t_zoMbjrCgGInhi+VE-?7@w-mS_^B zb23RV>%4=(2kF>nnD3fJm>5EcWwR;5i{E7yA~l1hBO&y}3dR^z-MCPE>}+Hj4qS}} zTi%2vK|UlAwnP(A(uWdeq;RiDECs%j2GrmxhXC1moxD{iuQ5%#qIjd%HVHrw^2eYa zLr_pKu{)6FshNC+!K1LwD8sFpd=_3gM@EdHw-J;tMWnXHNN{ZoV!Hw_P+@NIB#i|c zeyDz?0im3Lu1QN$>@;OU-U9#R&bJ3j7buesFRw{7=@kpAXJDWYJ(S5HR2qmy8GL78 z^-Rji47cs4^(;z-^TuE0Le!Kfho{)g?WSR5AXIiX4fIfQecym9Y+9T|Q@UC}oej)J zg={upBQitIiwmTC?1Fh;(GWE=DaW}sRnCI~u_QW?4UZ0qF!?blF!b4gGJ(GSD2za) z7X%MVjtO|T!Y{7ZT*>?)enGIzNBRca?+XlG=`2^snTq*i1JS=rW#qui2a^2ZNJ3s_ zQ`$HDmW64Glgc&@&hRt^zhrY1f()&lQ7~i`o47>F5t>9};%RpG6)UsbiYvznx9mG+-iF@wZh6FNZP{ zhQBh(>ebk!|Y1DHp)zHa*(x7KKdYIusL9@`hCN>=?~FT{O`3EnrsXjO&>YC zS)58SicYtX7L>aR+fUyBgSVqUrrfVnI9}MRvzqefXV-nOuj9C(Zz$!o$Rt!dj?}p} zNRe7vefi`~8T6Wm)dcgU>chhoP0pU(q@L{VC>XVyA^7tx3UqQV=C}Wi499mM=th;m zv1)xC1A|HY4ffI)2C{g64R`ylaGdfClCvinLCSiPRazR|%t8C9!?|a}Ug0+2!*_Bc z$Dg21ZGJJYqy&bcju_7w^KvOR+NXo6^O$TjNsrhr%A1TL_o+1qN28!(J<+FAC9Xm9 zrZ!zsP>N@jZ<4wkxk|tFv`PI63L7=fA(?vmJ@dlwC8@*IGZ9JEHWoALG+rgeptI_} z`S{r6q-lb2+uUZ?n#{t!x8lb{to>ggU%MYuhqP3E;d-TX7SnT zR0E>bQpr>iZAZ0>1?f$$#P8}9ZhC5V8p%cVmUIec8c051eGLKs-qi^B$!EO2d6X!$ zL=~)cZHAX{0N5Ww>J67tB5`8KZi9Da*tv9BRCo`H__fkhuJ_6^q(!nv+)wjRHRkrX zE5=Ks8Q&JG#vuj5=K}dp`14k{9ZnoGo@rF*>we+;iF2ZA+~|<`{1JLnT7TS57*ML)I+iwo6YV;q3vg=URlGYNxjDnwD!F{_%5V6id?xCn&(8h+7DPk z1mQjc>}vpz60vPOuF=x;$R8=Hj?mf;IwkoQl3Fnq0h9vSF5-vbM?_iI&Zoz?r05b3v!Q&IcXVjCVei{B_tPA@=lI@kSylvC0m2@ za5O*=YMI5-sBNK?E3Gx1Y>zRaSe`C)0FHvCOS9sFp72d*1SR}1Y1I|G@S~mespQHM zb8e~N;-A~z(sfN5ttsIi6%F(m^^clh_20cvL@8Ax*xL~IPw`adY^z$JdA0VWrz)@b zx)%?dcZXMX3Rnij5<3kKB{3vF}Z*) zJZI!w6|^e1o{TKy1P4(#a_Dv|>5dMSZM|axG-<^-+WX?nzVnsP>*$JUyr0^{nEZ{@ zMd(#jtLw6hPGNNSxb>YUpDQ!lsDsdopM)3|kJt7Tyo5A%;W_B3fkQ^UdP|8?$apCd zO8;dT>CP^M=}J#h3$6pFs9EVZi$;S~?8>Ddo+}z=HQJdak24#}0+cHs6!eH1?iEme2=wb z09N0OVk6el=*83m0;#6VJ_QbBBZ@xlapgx*H3};c5G6ZA%)o?VU*(Wl$j1vkdfjPA z<9y4jWd^Gru|gJCe2)LrAX*TAPgr=MjFVN43lG6WmnhkiU?@H`K6{4ep(L|kd8AB} zA+a&P_0_q~RaJIOdmWI;$F5eEyZrOd2=}6InGipX^W<-`^3##he_v6lQJIcOy$aw69(i^z+Xpl)(e+Dto#$i$baDXVKQ%o5KY1~gwB~MCh+{3MksH<8W+84ymb;3U^ z-B()t)cRG5S7V|*=SJhZ-nD*t?$i~3VdbaVT1#D;%?+l*Xx$nUw_&wBkqoA%5o0zV z%G6{%Evj|ov+hq_dZV`;VD?vZec{fm_SyNU_rCX4)r^9KRc7g+(~XL&-|e-~kFFKn zSB-7xdC~*Gww2z z!*S_|XPzxcmR#MvsBWqDd1+7` zINR0~#>6U~2^gocqxi&&rv$n*Lk)%s`Vu?{!6L@Q!MYAXb2PfckhVuOo_!;kXw)LX zBh24eg|h;37b}j@wM*xvH7hSKU*Bn_OMoJVhexw5j4z)uF;Vucj%M^^T)({QRRU#s zyef$&#YI7(l(ZDbYsk6>;_$-Ib37d2=j)~$;GIBRh32!g!{X8_a7Nfvlr4>z=c7O~ zK{_JtDHN%Q3OtqXrj>1jQZHwm$lMNDcyNqm5Cidhlg`?`<>O%JKW?ZtE2E8grk(

    <%= @controller_class %>Controller#<%= @action_name %>

    diff --git a/lib/generators/redmine_plugin_model/USAGE b/lib/generators/redmine_plugin_model/USAGE new file mode 100644 index 000000000..7b5d79857 --- /dev/null +++ b/lib/generators/redmine_plugin_model/USAGE @@ -0,0 +1,5 @@ +Description: + Generates a plugin model. + +Examples: + ./script/rails generate redmine_plugin_model meetings pool diff --git a/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb b/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb new file mode 100644 index 000000000..2e5f03108 --- /dev/null +++ b/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb @@ -0,0 +1,41 @@ +class RedminePluginModelGenerator < Rails::Generators::NamedBase + + source_root File.expand_path("../templates", __FILE__) + argument :model, :type => :string + argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]" + class_option :migration, :type => :boolean + class_option :timestamps, :type => :boolean + class_option :parent, :type => :string, :desc => "The parent class for the generated model" + class_option :indexes, :type => :boolean, :default => true, :desc => "Add indexes for references and belongs_to columns" + + attr_reader :plugin_path, :plugin_name, :plugin_pretty_name + + def initialize(*args) + super + @plugin_name = file_name.underscore + @plugin_pretty_name = plugin_name.titleize + @plugin_path = "plugins/#{plugin_name}" + @model_class = model.camelize + @table_name = @model_class.tableize + @migration_filename = "create_#{@table_name}" + @migration_class_name = @migration_filename.camelize + end + + def copy_templates + template 'model.rb.erb', "#{plugin_path}/app/models/#{model.underscore}.rb" + template 'unit_test.rb.erb', "#{plugin_path}/test/unit/#{model.underscore}_test.rb" + + migration_filename = "%03i_#{@migration_filename}.rb" % (migration_number + 1) + template "migration.rb", "#{plugin_path}/db/migrate/#{migration_filename}" + end + + def attributes_with_index + attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) } + end + + def migration_number + current = Dir.glob("#{plugin_path}/db/migrate/*.rb").map do |file| + File.basename(file).split("_").first.to_i + end.max.to_i + end +end diff --git a/lib/generators/redmine_plugin_model/templates/migration.rb b/lib/generators/redmine_plugin_model/templates/migration.rb new file mode 100644 index 000000000..f5026aebf --- /dev/null +++ b/lib/generators/redmine_plugin_model/templates/migration.rb @@ -0,0 +1,15 @@ +class <%= @migration_class_name %> < ActiveRecord::Migration + def change + create_table :<%= @table_name %> do |t| +<% attributes.each do |attribute| -%> + t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %> +<% end -%> +<% if options[:timestamps] %> + t.timestamps +<% end -%> + end +<% attributes_with_index.each do |attribute| -%> + add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> +<% end -%> + end +end diff --git a/lib/generators/redmine_plugin_model/templates/model.rb.erb b/lib/generators/redmine_plugin_model/templates/model.rb.erb new file mode 100644 index 000000000..71284e96d --- /dev/null +++ b/lib/generators/redmine_plugin_model/templates/model.rb.erb @@ -0,0 +1,3 @@ +class <%= @model_class %> < ActiveRecord::Base + unloadable +end diff --git a/lib/generators/redmine_plugin_model/templates/unit_test.rb.erb b/lib/generators/redmine_plugin_model/templates/unit_test.rb.erb new file mode 100644 index 000000000..ad15149fa --- /dev/null +++ b/lib/generators/redmine_plugin_model/templates/unit_test.rb.erb @@ -0,0 +1,9 @@ +require File.expand_path('../../test_helper', __FILE__) + +class <%= @model_class %>Test < ActiveSupport::TestCase + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/lib/plugins/acts-as-taggable-on/.rspec b/lib/plugins/acts-as-taggable-on/.rspec new file mode 100644 index 000000000..616c43385 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/.rspec @@ -0,0 +1,2 @@ +--colour +--backtrace diff --git a/lib/plugins/acts-as-taggable-on/.travis.yml b/lib/plugins/acts-as-taggable-on/.travis.yml new file mode 100644 index 000000000..576396e71 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/.travis.yml @@ -0,0 +1,9 @@ +script: "cp spec/database.yml.sample spec/database.yml && bundle install && bundle exec rake" +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 +env: + - DB=sqlite3 + - DB=mysql + - DB=postgresql \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/Appraisals b/lib/plugins/acts-as-taggable-on/Appraisals new file mode 100644 index 000000000..ad94b6262 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/Appraisals @@ -0,0 +1,7 @@ +appraise "rails-3" do + gem "rails", "3.2.13" +end + +appraise "rails-4" do + gem "rails", "4.0.0.beta1" +end diff --git a/lib/plugins/acts-as-taggable-on/Gemfile b/lib/plugins/acts-as-taggable-on/Gemfile new file mode 100644 index 000000000..e37a382a0 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gemspec + +gem 'appraisal' diff --git a/lib/plugins/acts-as-taggable-on/Guardfile b/lib/plugins/acts-as-taggable-on/Guardfile new file mode 100644 index 000000000..68512309b --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/Guardfile @@ -0,0 +1,5 @@ +guard 'rspec' do + watch(%r{^spec/.+_spec\.rb}) + watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } +end diff --git a/lib/plugins/acts-as-taggable-on/LICENSE.md b/lib/plugins/acts-as-taggable-on/LICENSE.md new file mode 100644 index 000000000..a68202301 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/LICENSE.md @@ -0,0 +1,20 @@ +__Copyright (c) 2007 Michael Bleigh and Intridea Inc.__ + +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 --git a/lib/plugins/acts-as-taggable-on/README.md b/lib/plugins/acts-as-taggable-on/README.md new file mode 100644 index 000000000..a67d267ce --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/README.md @@ -0,0 +1,303 @@ +# ActsAsTaggableOn +[![Build Status](https://secure.travis-ci.org/mbleigh/acts-as-taggable-on.png)](http://travis-ci.org/mbleigh/acts-as-taggable-on) + +This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney. +It has evolved substantially since that point, but all credit goes to him for the +initial tagging functionality that so many people have used. + +For instance, in a social network, a user might have tags that are called skills, +interests, sports, and more. There is no real way to differentiate between tags and +so an implementation of this type is not possible with acts as taggable on steroids. + +Enter Acts as Taggable On. Rather than tying functionality to a specific keyword +(namely `tags`), acts as taggable on allows you to specify an arbitrary number of +tag "contexts" that can be used locally or in combination in the same way steroids +was used. + +## Compatibility + +Versions 2.x are compatible with Ruby 1.8.7+ and Rails 3. + +Versions 2.4.1 and up are compatible with Rails 4 too (thanks to arabonradar and cwoodcox). + +Versions 3.x (currently unreleased) are compatible with Ruby 1.9.3+ and Rails 3 and 4. + +For an up-to-date roadmap, see https://github.com/mbleigh/acts-as-taggable-on/issues/milestones + +## Installation + +To use it, add it to your Gemfile: + +```ruby +gem 'acts-as-taggable-on' +``` + +and bundle: + +```ruby +bundle +``` + +#### Post Installation + +```shell +rails generate acts_as_taggable_on:migration +rake db:migrate +``` + +## Testing + +Acts As Taggable On uses RSpec for its test coverage. Inside the gem +directory, you can run the specs with: + +```shell +bundle +rake spec +``` + +If you want, add a `.ruby-version` file in the project root (and use rbenv or RVM) to work on a specific version of Ruby. + +## Usage + +```ruby +class User < ActiveRecord::Base + # Alias for acts_as_taggable_on :tags + acts_as_taggable + acts_as_taggable_on :skills, :interests +end + +@user = User.new(:name => "Bobby") +@user.tag_list = "awesome, slick, hefty" # this should be familiar +@user.skill_list = "joking, clowning, boxing" # but you can do it for any context! + +@user.tags # => [,,] +@user.skills # => [,,] +@user.skill_list # => ["joking","clowning","boxing"] as TagList + +@user.tag_list.remove("awesome") # remove a single tag +@user.tag_list.remove("awesome, slick") # works with arrays too +@user.tag_list.add("awesomer") # add a single tag. alias for << +@user.tag_list.add("awesomer, slicker") # also works with arrays + +User.skill_counts # => [,...] +``` + +To preserve the order in which tags are created use `acts_as_ordered_taggable`: + +```ruby +class User < ActiveRecord::Base + # Alias for acts_as_ordered_taggable_on :tags + acts_as_ordered_taggable + acts_as_ordered_taggable_on :skills, :interests +end + +@user = User.new(:name => "Bobby") +@user.tag_list = "east, south" +@user.save + +@user.tag_list = "north, east, south, west" +@user.save + +@user.reload +@user.tag_list # => ["north", "east", "south", "west"] +``` + +### Finding Tagged Objects + +Acts As Taggable On uses scopes to create an association for tags. +This way you can mix and match to filter down your results. + +```ruby +class User < ActiveRecord::Base + acts_as_taggable_on :tags, :skills + scope :by_join_date, order("created_at DESC") +end + +User.tagged_with("awesome").by_join_date +User.tagged_with("awesome").by_join_date.paginate(:page => params[:page], :per_page => 20) + +# Find a user with matching all tags, not just one +User.tagged_with(["awesome", "cool"], :match_all => true) + +# Find a user with any of the tags: +User.tagged_with(["awesome", "cool"], :any => true) + +# Find a user that not tags with awesome or cool: +User.tagged_with(["awesome", "cool"], :exclude => true) + +# Find a user with any of tags based on context: +User.tagged_with(['awesome, cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true) +``` + +You can also use `:wild => true` option along with `:any` or `:exclude` option. It will looking for `%awesome%` and `%cool%` in sql. + +__Tip:__ `User.tagged_with([])` or '' will return `[]`, but not all records. + +### Relationships + +You can find objects of the same type based on similar tags on certain contexts. +Also, objects will be returned in descending order based on the total number of +matched tags. + +```ruby +@bobby = User.find_by_name("Bobby") +@bobby.skill_list # => ["jogging", "diving"] + +@frankie = User.find_by_name("Frankie") +@frankie.skill_list # => ["hacking"] + +@tom = User.find_by_name("Tom") +@tom.skill_list # => ["hacking", "jogging", "diving"] + +@tom.find_related_skills # => [,] +@bobby.find_related_skills # => [] +@frankie.find_related_skills # => [] +``` + +### Dynamic Tag Contexts + +In addition to the generated tag contexts in the definition, it is also possible +to allow for dynamic tag contexts (this could be user generated tag contexts!) + +```ruby +@user = User.new(:name => "Bobby") +@user.set_tag_list_on(:customs, "same, as, tag, list") +@user.tag_list_on(:customs) # => ["same","as","tag","list"] +@user.save +@user.tags_on(:customs) # => [,...] +@user.tag_counts_on(:customs) +User.tagged_with("same", :on => :customs) # => [@user] +``` + +### Tag Ownership + +Tags can have owners: + +```ruby +class User < ActiveRecord::Base + acts_as_tagger +end + +class Photo < ActiveRecord::Base + acts_as_taggable_on :locations +end + +@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations) +@some_user.owned_taggings +@some_user.owned_tags +Photo.tagged_with("paris", :on => :locations, :owned_by => @some_user) +@some_photo.locations_from(@some_user) # => ["paris", "normandy"] +@some_photo.owner_tags_on(@some_user, :locations) # => [#...] +@some_photo.owner_tags_on(nil, :locations) # => Ownerships equivalent to saying @some_photo.locations +@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations, :skip_save => true) #won't save @some_photo object +``` + +### Dirty objects + +```ruby +@bobby = User.find_by_name("Bobby") +@bobby.skill_list # => ["jogging", "diving"] + +@bobby.skill_list_changed? #=> false +@bobby.changes #=> {} + +@bobby.skill_list = "swimming" +@bobby.changes.should == {"skill_list"=>["jogging, diving", ["swimming"]]} +@bobby.skill_list_changed? #=> true + +@bobby.skill_list_change.should == ["jogging, diving", ["swimming"]] +``` + +### Tag cloud calculations + +To construct tag clouds, the frequency of each tag needs to be calculated. +Because we specified `acts_as_taggable_on` on the `User` class, we can +get a calculation of all the tag counts by using `User.tag_counts_on(:customs)`. But what if we wanted a tag count for +an single user's posts? To achieve this we call tag_counts on the association: + +```ruby +User.find(:first).posts.tag_counts_on(:tags) +``` + +A helper is included to assist with generating tag clouds. + +Here is an example that generates a tag cloud. + +Helper: + +```ruby +module PostsHelper + include ActsAsTaggableOn::TagsHelper +end +``` + +Controller: + +```ruby +class PostController < ApplicationController + def tag_cloud + @tags = Post.tag_counts_on(:tags) + end +end +``` + +View: + +```erb +<% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %> + <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %> +<% end %> +``` + +CSS: + +```css +.css1 { font-size: 1.0em; } +.css2 { font-size: 1.2em; } +.css3 { font-size: 1.4em; } +.css4 { font-size: 1.6em; } +``` + +## Configuration + +If you would like to remove unused tag objects after removing taggings, add: + +```ruby +ActsAsTaggableOn.remove_unused_tags = true +``` + +If you want force tags to be saved downcased: + +```ruby +ActsAsTaggableOn.force_lowercase = true +``` + +If you want tags to be saved parametrized (you can redefine to_param as well): + +```ruby +ActsAsTaggableOn.force_parameterize = true +``` + +If you would like tags to be case-sensitive and not use LIKE queries for creation: + +```ruby +ActsAsTaggableOn.strict_case_match = true +``` + +If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']): + +```ruby +ActsAsTaggableOn.delimiter = ',' +``` + +## Contributors + +We have a long list of valued contributors. [Check them all](https://github.com/mbleigh/acts-as-taggable-on/contributors) + +## Maintainer + +* [Joost Baaij](https://github.com/tilsammans) + +## License + +See [LICENSE](https://github.com/mbleigh/acts-as-taggable-on/blob/master/LICENSE.md) diff --git a/lib/plugins/acts-as-taggable-on/Rakefile b/lib/plugins/acts-as-taggable-on/Rakefile new file mode 100644 index 000000000..a81fa40d8 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/Rakefile @@ -0,0 +1,13 @@ +require 'rubygems' +require 'bundler/setup' +require 'appraisal' + +desc 'Default: run specs' +task :default => :spec + +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new do |t| + t.pattern = "spec/**/*_spec.rb" +end + +Bundler::GemHelper.install_tasks diff --git a/lib/plugins/acts-as-taggable-on/acts-as-taggable-on.gemspec b/lib/plugins/acts-as-taggable-on/acts-as-taggable-on.gemspec new file mode 100644 index 000000000..f4240504a --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/acts-as-taggable-on.gemspec @@ -0,0 +1,35 @@ +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'acts_as_taggable_on/version' + +Gem::Specification.new do |gem| + gem.name = "acts-as-taggable-on" + gem.version = ActsAsTaggableOn::VERSION + gem.authors = ["Michael Bleigh", "Joost Baaij"] + gem.email = ["michael@intridea.com", "joost@spacebabies.nl"] + gem.description = %q{With ActsAsTaggableOn, you can tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality.} + gem.summary = "Advanced tagging for Rails." + gem.homepage = 'https://github.com/mbleigh/acts-as-taggable-on' + gem.license = "MIT" + + gem.files = `git ls-files`.split($/) + gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.require_paths = ["lib"] + + if File.exists?('UPGRADING') + gem.post_install_message = File.read('UPGRADING') + end + + gem.add_runtime_dependency 'rails', ['>= 3', '< 5'] + + gem.add_development_dependency 'rspec-rails', '2.13.0' # 2.13.1 is broken + gem.add_development_dependency 'rspec', '~> 2.6' + gem.add_development_dependency 'ammeter' + gem.add_development_dependency 'sqlite3' + gem.add_development_dependency 'mysql2', '~> 0.3.7' + gem.add_development_dependency 'pg' + gem.add_development_dependency 'guard' + gem.add_development_dependency 'guard-rspec' +end diff --git a/lib/plugins/acts-as-taggable-on/gemfiles/rails_3.gemfile b/lib/plugins/acts-as-taggable-on/gemfiles/rails_3.gemfile new file mode 100644 index 000000000..19f525c52 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/gemfiles/rails_3.gemfile @@ -0,0 +1,8 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "rails", "3.2.13" + +gemspec :path=>"../" \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/gemfiles/rails_4.gemfile b/lib/plugins/acts-as-taggable-on/gemfiles/rails_4.gemfile new file mode 100644 index 000000000..2bf10158b --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/gemfiles/rails_4.gemfile @@ -0,0 +1,8 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "rails", :github => 'rails/rails' + +gemspec :path=>"../" \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/lib/acts-as-taggable-on.rb b/lib/plugins/acts-as-taggable-on/lib/acts-as-taggable-on.rb new file mode 100644 index 000000000..7a6e116c2 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts-as-taggable-on.rb @@ -0,0 +1,65 @@ +require "active_record" +require "active_record/version" +require "action_view" + +require "digest/sha1" + +$LOAD_PATH.unshift(File.dirname(__FILE__)) + +module ActsAsTaggableOn + mattr_accessor :delimiter + @@delimiter = ',' + + mattr_accessor :force_lowercase + @@force_lowercase = false + + mattr_accessor :force_parameterize + @@force_parameterize = false + + mattr_accessor :strict_case_match + @@strict_case_match = false + + mattr_accessor :remove_unused_tags + self.remove_unused_tags = false + + def self.glue + delimiter = @@delimiter.kind_of?(Array) ? @@delimiter[0] : @@delimiter + delimiter.ends_with?(" ") ? delimiter : "#{delimiter} " + end + + def self.setup + yield self + end +end + + +require "acts_as_taggable_on/utils" + +require "acts_as_taggable_on/taggable" +require "acts_as_taggable_on/acts_as_taggable_on/compatibility" +require "acts_as_taggable_on/acts_as_taggable_on/core" +require "acts_as_taggable_on/acts_as_taggable_on/collection" +require "acts_as_taggable_on/acts_as_taggable_on/cache" +require "acts_as_taggable_on/acts_as_taggable_on/ownership" +require "acts_as_taggable_on/acts_as_taggable_on/related" +require "acts_as_taggable_on/acts_as_taggable_on/dirty" + +require "acts_as_taggable_on/tagger" +require "acts_as_taggable_on/tag" +require "acts_as_taggable_on/tag_list" +require "acts_as_taggable_on/tags_helper" +require "acts_as_taggable_on/tagging" + +$LOAD_PATH.shift + + +if defined?(ActiveRecord::Base) + ActiveRecord::Base.extend ActsAsTaggableOn::Compatibility + ActiveRecord::Base.extend ActsAsTaggableOn::Taggable + ActiveRecord::Base.send :include, ActsAsTaggableOn::Tagger +end + +if defined?(ActionView::Base) + ActionView::Base.send :include, ActsAsTaggableOn::TagsHelper +end + diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb new file mode 100644 index 000000000..6bec623de --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb @@ -0,0 +1,53 @@ +module ActsAsTaggableOn::Taggable + module Cache + def self.included(base) + # Skip adding caching capabilities if table not exists or no cache columns exist + return unless base.table_exists? && base.tag_types.any? { |context| base.column_names.include?("cached_#{context.to_s.singularize}_list") } + + base.send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods + base.extend ActsAsTaggableOn::Taggable::Cache::ClassMethods + + base.class_eval do + before_save :save_cached_tag_list + end + + base.initialize_acts_as_taggable_on_cache + end + + module ClassMethods + def initialize_acts_as_taggable_on_cache + tag_types.map(&:to_s).each do |tag_type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def self.caching_#{tag_type.singularize}_list? + caching_tag_list_on?("#{tag_type}") + end + RUBY + end + end + + def acts_as_taggable_on(*args) + super(*args) + initialize_acts_as_taggable_on_cache + end + + def caching_tag_list_on?(context) + column_names.include?("cached_#{context.to_s.singularize}_list") + end + end + + module InstanceMethods + def save_cached_tag_list + tag_types.map(&:to_s).each do |tag_type| + if self.class.send("caching_#{tag_type.singularize}_list?") + if tag_list_cache_set_on(tag_type) + list = tag_list_cache_on(tag_type).to_a.flatten.compact.join(', ') + self["cached_#{tag_type.singularize}_list"] = list + end + end + end + + true + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb new file mode 100644 index 000000000..60eb4bd6e --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb @@ -0,0 +1,183 @@ +module ActsAsTaggableOn::Taggable + module Collection + def self.included(base) + base.send :include, ActsAsTaggableOn::Taggable::Collection::InstanceMethods + base.extend ActsAsTaggableOn::Taggable::Collection::ClassMethods + base.initialize_acts_as_taggable_on_collection + end + + module ClassMethods + def initialize_acts_as_taggable_on_collection + tag_types.map(&:to_s).each do |tag_type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def self.#{tag_type.singularize}_counts(options={}) + tag_counts_on('#{tag_type}', options) + end + + def #{tag_type.singularize}_counts(options = {}) + tag_counts_on('#{tag_type}', options) + end + + def top_#{tag_type}(limit = 10) + tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i) + end + + def self.top_#{tag_type}(limit = 10) + tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i) + end + RUBY + end + end + + def acts_as_taggable_on(*args) + super(*args) + initialize_acts_as_taggable_on_collection + end + + def tag_counts_on(context, options = {}) + all_tag_counts(options.merge({:on => context.to_s})) + end + + def tags_on(context, options = {}) + all_tags(options.merge({:on => context.to_s})) + end + + ## + # Calculate the tag names. + # To be used when you don't need tag counts and want to avoid the taggable joins. + # + # @param [Hash] options Options: + # * :start_at - Restrict the tags to those created after a certain time + # * :end_at - Restrict the tags to those created before a certain time + # * :conditions - A piece of SQL conditions to add to the query. Note we don't join the taggable objects for performance reasons. + # * :limit - The maximum number of tags to return + # * :order - A piece of SQL to order by. Eg 'tags.count desc' or 'taggings.created_at desc' + # * :on - Scope the find to only include a certain context + def all_tags(options = {}) + options.assert_valid_keys :start_at, :end_at, :conditions, :order, :limit, :on + + ## Generate conditions: + options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions] + + start_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at] + end_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at] + + taggable_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.taggable_type = ?", base_class.name]) + taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on] + + tagging_conditions = [ + taggable_conditions, + start_at_conditions, + end_at_conditions + ].compact.reverse + + tag_conditions = [ + options[:conditions] + ].compact.reverse + + ## Generate scope: + tagging_scope = ActsAsTaggableOn::Tagging.select("#{ActsAsTaggableOn::Tagging.table_name}.tag_id") + tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*").order(options[:order]).limit(options[:limit]) + + # Joins and conditions + tagging_conditions.each { |condition| tagging_scope = tagging_scope.where(condition) } + tag_conditions.each { |condition| tag_scope = tag_scope.where(condition) } + + group_columns = "#{ActsAsTaggableOn::Tagging.table_name}.tag_id" + + # Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore: + scoped_select = "#{table_name}.#{primary_key}" + tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{select(scoped_select).to_sql})").group(group_columns) + + tag_scope = tag_scope.joins("JOIN (#{tagging_scope.to_sql}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id") + tag_scope + end + + ## + # Calculate the tag counts for all tags. + # + # @param [Hash] options Options: + # * :start_at - Restrict the tags to those created after a certain time + # * :end_at - Restrict the tags to those created before a certain time + # * :conditions - A piece of SQL conditions to add to the query + # * :limit - The maximum number of tags to return + # * :order - A piece of SQL to order by. Eg 'tags.count desc' or 'taggings.created_at desc' + # * :at_least - Exclude tags with a frequency less than the given value + # * :at_most - Exclude tags with a frequency greater than the given value + # * :on - Scope the find to only include a certain context + def all_tag_counts(options = {}) + options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :on, :id + + scope = {} + + ## Generate conditions: + options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions] + + start_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at] + end_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at] + + taggable_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.taggable_type = ?", base_class.name]) + taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = ?", options[:id]]) if options[:id] + taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on] + + tagging_conditions = [ + taggable_conditions, + scope[:conditions], + start_at_conditions, + end_at_conditions + ].compact.reverse + + tag_conditions = [ + options[:conditions] + ].compact.reverse + + ## Generate joins: + taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id" + taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'" unless descends_from_active_record? # Current model is STI descendant, so add type checking to the join condition + + tagging_joins = [ + taggable_join, + scope[:joins] + ].compact + + tag_joins = [ + ].compact + + ## Generate scope: + tagging_scope = ActsAsTaggableOn::Tagging.select("#{ActsAsTaggableOn::Tagging.table_name}.tag_id, COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) AS tags_count") + tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*, #{ActsAsTaggableOn::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit]) + + # Joins and conditions + tagging_joins.each { |join| tagging_scope = tagging_scope.joins(join) } + tagging_conditions.each { |condition| tagging_scope = tagging_scope.where(condition) } + + tag_joins.each { |join| tag_scope = tag_scope.joins(join) } + tag_conditions.each { |condition| tag_scope = tag_scope.where(condition) } + + # GROUP BY and HAVING clauses: + at_least = sanitize_sql(["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) >= ?", options.delete(:at_least)]) if options[:at_least] + at_most = sanitize_sql(["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) <= ?", options.delete(:at_most)]) if options[:at_most] + having = ["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) > 0", at_least, at_most].compact.join(' AND ') + + group_columns = "#{ActsAsTaggableOn::Tagging.table_name}.tag_id" + + unless options[:id] + # Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore: + scoped_select = "#{table_name}.#{primary_key}" + tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{select(scoped_select).to_sql})") + end + + tagging_scope = tagging_scope.group(group_columns).having(having) + + tag_scope = tag_scope.joins("JOIN (#{tagging_scope.to_sql}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id") + tag_scope + end + end + + module InstanceMethods + def tag_counts_on(context, options={}) + self.class.tag_counts_on(context, options.merge(:id => id)) + end + end + end +end \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb new file mode 100644 index 000000000..488445dcb --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb @@ -0,0 +1,34 @@ +module ActsAsTaggableOn::Compatibility + def has_many_with_compatibility(name, options = {}, &extention) + if ActiveRecord::VERSION::MAJOR >= 4 + scope, opts = build_scope_and_options(options) + has_many(name, scope, opts, &extention) + else + has_many(name, options, &extention) + end + end + + def build_scope_and_options(opts) + scope_opts, opts = parse_options(opts) + + unless scope_opts.empty? + scope = lambda do + scope_opts.inject(self) { |result, hash| result.send *hash } ##原æ¥ä»£ç ç”¨çš„æ˜¯ *hash + end + end + + [defined?(scope) ? scope : nil, opts] + end + + def parse_options(opts) + scope_opts = {} + [:order, :having, :select, :group, :limit, :offset, :readonly].each do |o| + scope_opts[o] = opts.delete o if opts[o] + end + scope_opts[:where] = opts.delete :conditions if opts[:conditions] + scope_opts[:joins] = opts.delete :include if opts [:include] + scope_opts[:distinct] = opts.delete :uniq if opts[:uniq] + + [scope_opts, opts] + end +end \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb new file mode 100644 index 000000000..8ca6962fd --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb @@ -0,0 +1,388 @@ +module ActsAsTaggableOn::Taggable + module Core + def self.included(base) + base.send :include, ActsAsTaggableOn::Taggable::Core::InstanceMethods + base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods + + base.class_eval do + attr_writer :custom_contexts + after_save :save_tags + end + + base.initialize_acts_as_taggable_on_core + end + + module ClassMethods + + def initialize_acts_as_taggable_on_core + include taggable_mixin + tag_types.map(&:to_s).each do |tags_type| + tag_type = tags_type.to_s.singularize + context_taggings = "#{tag_type}_taggings".to_sym + context_tags = tags_type.to_sym + taggings_order = (preserve_tag_order? ? "#{ActsAsTaggableOn::Tagging.table_name}.id" : []) + + class_eval do + # when preserving tag order, include order option so that for a 'tags' context + # the associations tag_taggings & tags are always returned in created order + has_many_with_compatibility context_taggings, :as => :taggable, + :dependent => :destroy, + :class_name => "ActsAsTaggableOn::Tagging", + :order => taggings_order, + :conditions => ["#{ActsAsTaggableOn::Tagging.table_name}.context = (?)", tags_type], + :include => :tag + + has_many_with_compatibility context_tags, :through => context_taggings, + :source => :tag, + :class_name => "ActsAsTaggableOn::Tag", + :order => taggings_order + + end + + taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{tag_type}_list + tag_list_on('#{tags_type}') + end + + def #{tag_type}_list=(new_tags) + set_tag_list_on('#{tags_type}', new_tags) + end + + def all_#{tags_type}_list + all_tags_list_on('#{tags_type}') + end + RUBY + end + end + + def taggable_on(preserve_tag_order, *tag_types) + super(preserve_tag_order, *tag_types) + initialize_acts_as_taggable_on_core + end + + # all column names are necessary for PostgreSQL group clause + def grouped_column_names_for(object) + object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ") + end + + ## + # Return a scope of objects that are tagged with the specified tags. + # + # @param tags The tags that we want to query for + # @param [Hash] options A hash of options to alter you query: + # * :exclude - if set to true, return objects that are *NOT* tagged with the specified tags + # * :any - if set to true, return objects that are tagged with *ANY* of the specified tags + # * :match_all - if set to true, return objects that are *ONLY* tagged with the specified tags + # * :owned_by - return objects that are *ONLY* owned by the owner + # + # Example: + # User.tagged_with("awesome", "cool") # Users that are tagged with awesome and cool + # User.tagged_with("awesome", "cool", :exclude => true) # Users that are not tagged with awesome or cool + # User.tagged_with("awesome", "cool", :any => true) # Users that are tagged with awesome or cool + # User.tagged_with("awesome", "cool", :match_all => true) # Users that are tagged with just awesome and cool + # User.tagged_with("awesome", "cool", :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo' + def tagged_with(tags, options = {}) + tag_list = ActsAsTaggableOn::TagList.from(tags) + empty_result = where("1 = 0") + + return empty_result if tag_list.empty? + + joins = [] + conditions = [] + having = [] + select_clause = [] + + context = options.delete(:on) + owned_by = options.delete(:owned_by) + alias_base_name = undecorated_table_name.gsub('.','_') + quote = ActsAsTaggableOn::Tag.using_postgresql? ? '"' : '' + + if options.delete(:exclude) + if options.delete(:wild) + tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ? ESCAPE '!'", "%#{escape_like(t)}%"]) }.join(" OR ") + else + tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ") + end + + conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})" + + if owned_by + joins << "JOIN #{ActsAsTaggableOn::Tagging.table_name}" + + " ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" + + " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" + + " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{owned_by.id}" + + " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s)}" + end + + elsif options.delete(:any) + # get tags, drop out if nothing returned (we need at least one) + tags = if options.delete(:wild) + ActsAsTaggableOn::Tag.named_like_any(tag_list) + else + ActsAsTaggableOn::Tag.named_any(tag_list) + end + + return empty_result unless tags.length > 0 + + # setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123 + # avoid ambiguous column name + taggings_context = context ? "_#{context}" : '' + + taggings_alias = adjust_taggings_alias( + "#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{sha_prefix(tags.map(&:name).join('_'))}" + ) + + tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + + " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" + + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" + tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context + + # don't need to sanitize sql, map all ids and join with OR logic + conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ") + select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one? + + if owned_by + tagging_join << " AND " + + sanitize_sql([ + "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", + owned_by.id, + owned_by.class.base_class.to_s + ]) + end + + joins << tagging_join + else + tags = ActsAsTaggableOn::Tag.named_any(tag_list) + + return empty_result unless tags.length == tag_list.length + + tags.each do |tag| + taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}") + tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + + " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" + + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" + + " AND #{taggings_alias}.tag_id = #{tag.id}" + + tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context + + if owned_by + tagging_join << " AND " + + sanitize_sql([ + "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", + owned_by.id, + owned_by.class.base_class.to_s + ]) + end + + joins << tagging_join + end + end + + taggings_alias, tags_alias = adjust_taggings_alias("#{alias_base_name}_taggings_group"), "#{alias_base_name}_tags_group" + + if options.delete(:match_all) + joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + + " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" + + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" + + + group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}" + group = group_columns + having = "COUNT(#{taggings_alias}.taggable_id) = #{tags.size}" + end + + select(select_clause) \ + .joins(joins.join(" ")) \ + .where(conditions.join(" AND ")) \ + .group(group) \ + .having(having) \ + .order(options[:order]) \ + .readonly(false) + end + + def is_taggable? + true + end + + def adjust_taggings_alias(taggings_alias) + if taggings_alias.size > 75 + taggings_alias = 'taggings_alias_' + Digest::SHA1.hexdigest(taggings_alias) + end + taggings_alias + end + + def taggable_mixin + @taggable_mixin ||= Module.new + end + end + + module InstanceMethods + # all column names are necessary for PostgreSQL group clause + def grouped_column_names_for(object) + self.class.grouped_column_names_for(object) + end + + def custom_contexts + @custom_contexts ||= [] + end + + def is_taggable? + self.class.is_taggable? + end + + def add_custom_context(value) + custom_contexts << value.to_s unless custom_contexts.include?(value.to_s) or self.class.tag_types.map(&:to_s).include?(value.to_s) + end + + def cached_tag_list_on(context) + self["cached_#{context.to_s.singularize}_list"] + end + + def tag_list_cache_set_on(context) + variable_name = "@#{context.to_s.singularize}_list" + instance_variable_defined?(variable_name) && !instance_variable_get(variable_name).nil? + end + + def tag_list_cache_on(context) + variable_name = "@#{context.to_s.singularize}_list" + if instance_variable_get(variable_name) + instance_variable_get(variable_name) + elsif cached_tag_list_on(context) && self.class.caching_tag_list_on?(context) + instance_variable_set(variable_name, ActsAsTaggableOn::TagList.from(cached_tag_list_on(context))) + else + instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name))) + end + end + + def tag_list_on(context) + add_custom_context(context) + tag_list_cache_on(context) + end + + def all_tags_list_on(context) + variable_name = "@all_#{context.to_s.singularize}_list" + return instance_variable_get(variable_name) if instance_variable_defined?(variable_name) && instance_variable_get(variable_name) + + instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(all_tags_on(context).map(&:name)).freeze) + end + + ## + # Returns all tags of a given context + def all_tags_on(context) + tag_table_name = ActsAsTaggableOn::Tag.table_name + tagging_table_name = ActsAsTaggableOn::Tagging.table_name + + opts = ["#{tagging_table_name}.context = ?", context.to_s] + scope = base_tags.where(opts) + + if ActsAsTaggableOn::Tag.using_postgresql? + group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag) + scope.order("max(#{tagging_table_name}.created_at)").group(group_columns) + else + scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}") + end.to_a + end + + ## + # Returns all tags that are not owned of a given context + def tags_on(context) + scope = base_tags.where(["#{ActsAsTaggableOn::Tagging.table_name}.context = ? AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id IS NULL", context.to_s]) + # when preserving tag order, return tags in created order + # if we added the order to the association this would always apply + scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") if self.class.preserve_tag_order? + scope + end + + def set_tag_list_on(context, new_list) + add_custom_context(context) + + variable_name = "@#{context.to_s.singularize}_list" + process_dirty_object(context, new_list) unless custom_contexts.include?(context.to_s) + + instance_variable_set(variable_name, ActsAsTaggableOn::TagList.from(new_list)) + end + + def tagging_contexts + custom_contexts + self.class.tag_types.map(&:to_s) + end + + def process_dirty_object(context,new_list) + value = new_list.is_a?(Array) ? new_list.join(', ') : new_list + attrib = "#{context.to_s.singularize}_list" + + if changed_attributes.include?(attrib) + # The attribute already has an unsaved change. + old = changed_attributes[attrib] + changed_attributes.delete(attrib) if (old.to_s == value.to_s) + else + old = tag_list_on(context).to_s + changed_attributes[attrib] = old if (old.to_s != value.to_s) + end + end + + def reload(*args) + self.class.tag_types.each do |context| + instance_variable_set("@#{context.to_s.singularize}_list", nil) + instance_variable_set("@all_#{context.to_s.singularize}_list", nil) + end + + super(*args) + end + + def save_tags + tagging_contexts.each do |context| + next unless tag_list_cache_set_on(context) + # List of currently assigned tag names + tag_list = tag_list_cache_on(context).uniq + + # Find existing tags or create non-existing tags: + tags = ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list) + + # Tag objects for currently assigned tags + current_tags = tags_on(context) + + # Tag maintenance based on whether preserving the created order of tags + if self.class.preserve_tag_order? + old_tags, new_tags = current_tags - tags, tags - current_tags + + shared_tags = current_tags & tags + + if shared_tags.any? && tags[0...shared_tags.size] != shared_tags + index = shared_tags.each_with_index { |_, i| break i unless shared_tags[i] == tags[i] } + + # Update arrays of tag objects + old_tags |= current_tags[index...current_tags.size] + new_tags |= current_tags[index...current_tags.size] & shared_tags + + # Order the array of tag objects to match the tag list + new_tags = tags.map do |t| + new_tags.find { |n| n.name.downcase == t.name.downcase } + end.compact + end + else + # Delete discarded tags and create new tags + old_tags = current_tags - tags + new_tags = tags - current_tags + end + + # Find taggings to remove: + if old_tags.present? + old_taggings = taggings.where(:tagger_type => nil, :tagger_id => nil, :context => context.to_s, :tag_id => old_tags) + end + + # Destroy old taggings: + if old_taggings.present? + ActsAsTaggableOn::Tagging.destroy_all "#{ActsAsTaggableOn::Tagging.primary_key}".to_sym => old_taggings.map(&:id) + end + + # Create new taggings: + new_tags.each do |tag| + taggings.create!(:tag_id => tag.id, :context => context.to_s, :taggable => self) + end + end + + true + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb new file mode 100644 index 000000000..2bc036842 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb @@ -0,0 +1,37 @@ +module ActsAsTaggableOn::Taggable + module Dirty + def self.included(base) + base.extend ActsAsTaggableOn::Taggable::Dirty::ClassMethods + + base.initialize_acts_as_taggable_on_dirty + end + + module ClassMethods + def initialize_acts_as_taggable_on_dirty + tag_types.map(&:to_s).each do |tags_type| + tag_type = tags_type.to_s.singularize + context_tags = tags_type.to_sym + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{tag_type}_list_changed? + changed_attributes.include?("#{tag_type}_list") + end + + def #{tag_type}_list_was + changed_attributes.include?("#{tag_type}_list") ? changed_attributes["#{tag_type}_list"] : __send__("#{tag_type}_list") + end + + def #{tag_type}_list_change + [changed_attributes['#{tag_type}_list'], __send__('#{tag_type}_list')] if changed_attributes.include?("#{tag_type}_list") + end + + def #{tag_type}_list_changes + [changed_attributes['#{tag_type}_list'], __send__('#{tag_type}_list')] if changed_attributes.include?("#{tag_type}_list") + end + RUBY + + end + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb new file mode 100644 index 000000000..7b945957a --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb @@ -0,0 +1,135 @@ +module ActsAsTaggableOn::Taggable + module Ownership + def self.included(base) + base.send :include, ActsAsTaggableOn::Taggable::Ownership::InstanceMethods + base.extend ActsAsTaggableOn::Taggable::Ownership::ClassMethods + + base.class_eval do + after_save :save_owned_tags + end + + base.initialize_acts_as_taggable_on_ownership + end + + module ClassMethods + def acts_as_taggable_on(*args) + initialize_acts_as_taggable_on_ownership + super(*args) + end + + def initialize_acts_as_taggable_on_ownership + tag_types.map(&:to_s).each do |tag_type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{tag_type}_from(owner) + owner_tag_list_on(owner, '#{tag_type}') + end + RUBY + end + end + end + + module InstanceMethods + def owner_tags_on(owner, context) + if owner.nil? + scope = base_tags.where([%(#{ActsAsTaggableOn::Tagging.table_name}.context = ?), context.to_s]) + else + scope = base_tags.where([%(#{ActsAsTaggableOn::Tagging.table_name}.context = ? AND + #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = ? AND + #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = ?), context.to_s, owner.id, owner.class.base_class.to_s]) + end + + # when preserving tag order, return tags in created order + # if we added the order to the association this would always apply + if self.class.preserve_tag_order? + scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") + else + scope + end + end + + def cached_owned_tag_list_on(context) + variable_name = "@owned_#{context}_list" + cache = (instance_variable_defined?(variable_name) && instance_variable_get(variable_name)) || instance_variable_set(variable_name, {}) + end + + def owner_tag_list_on(owner, context) + add_custom_context(context) + + cache = cached_owned_tag_list_on(context) + + cache[owner] ||= ActsAsTaggableOn::TagList.new(*owner_tags_on(owner, context).map(&:name)) + end + + def set_owner_tag_list_on(owner, context, new_list) + add_custom_context(context) + + cache = cached_owned_tag_list_on(context) + + cache[owner] = ActsAsTaggableOn::TagList.from(new_list) + end + + def reload(*args) + self.class.tag_types.each do |context| + instance_variable_set("@owned_#{context}_list", nil) + end + + super(*args) + end + + def save_owned_tags + tagging_contexts.each do |context| + cached_owned_tag_list_on(context).each do |owner, tag_list| + + # Find existing tags or create non-existing tags: + tags = ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list.uniq) + + # Tag objects for owned tags + owned_tags = owner_tags_on(owner, context) + + # Tag maintenance based on whether preserving the created order of tags + if self.class.preserve_tag_order? + old_tags, new_tags = owned_tags - tags, tags - owned_tags + + shared_tags = owned_tags & tags + + if shared_tags.any? && tags[0...shared_tags.size] != shared_tags + index = shared_tags.each_with_index { |_, i| break i unless shared_tags[i] == tags[i] } + + # Update arrays of tag objects + old_tags |= owned_tags.from(index) + new_tags |= owned_tags.from(index) & shared_tags + + # Order the array of tag objects to match the tag list + new_tags = tags.map { |t| new_tags.find { |n| n.name.downcase == t.name.downcase } }.compact + end + else + # Delete discarded tags and create new tags + old_tags = owned_tags - tags + new_tags = tags - owned_tags + end + + # Find all taggings that belong to the taggable (self), are owned by the owner, + # have the correct context, and are removed from the list. + if old_tags.present? + old_taggings = ActsAsTaggableOn::Tagging.where(:taggable_id => id, :taggable_type => self.class.base_class.to_s, + :tagger_type => owner.class.base_class.to_s, :tagger_id => owner.id, + :tag_id => old_tags, :context => context) + end + + # Destroy old taggings: + if old_taggings.present? + ActsAsTaggableOn::Tagging.destroy_all(:id => old_taggings.map(&:id)) + end + + # Create new taggings: + new_tags.each do |tag| + taggings.create!(:tag_id => tag.id, :context => context.to_s, :tagger => owner, :taggable => self) + end + end + end + + true + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb new file mode 100644 index 000000000..98f3d3c2f --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb @@ -0,0 +1,84 @@ +module ActsAsTaggableOn::Taggable + module Related + def self.included(base) + base.send :include, ActsAsTaggableOn::Taggable::Related::InstanceMethods + base.extend ActsAsTaggableOn::Taggable::Related::ClassMethods + base.initialize_acts_as_taggable_on_related + end + + module ClassMethods + def initialize_acts_as_taggable_on_related + tag_types.map(&:to_s).each do |tag_type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def find_related_#{tag_type}(options = {}) + related_tags_for('#{tag_type}', self.class, options) + end + alias_method :find_related_on_#{tag_type}, :find_related_#{tag_type} + + def find_related_#{tag_type}_for(klass, options = {}) + related_tags_for('#{tag_type}', klass, options) + end + RUBY + end + + unless tag_types.empty? + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def find_matching_contexts(search_context, result_context, options = {}) + matching_contexts_for(search_context.to_s, result_context.to_s, self.class, options) + end + + def find_matching_contexts_for(klass, search_context, result_context, options = {}) + matching_contexts_for(search_context.to_s, result_context.to_s, klass, options) + end + RUBY + end + end + + def acts_as_taggable_on(*args) + super(*args) + initialize_acts_as_taggable_on_related + end + end + + module InstanceMethods + def matching_contexts_for(search_context, result_context, klass, options = {}) + tags_to_find = tags_on(search_context).collect { |t| t.name } + + klass.select("#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count") \ + .from("#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}") \ + .where(["#{exclude_self(klass, id)} #{klass.table_name}.#{klass.primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.base_class.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?) AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_to_find, result_context]) \ + .group(group_columns(klass)) \ + .order("count DESC") + end + + def related_tags_for(context, klass, options = {}) + tags_to_ignore = Array.wrap(options.delete(:ignore)).map(&:to_s) || [] + tags_to_find = tags_on(context).collect { |t| t.name }.reject { |t| tags_to_ignore.include? t } + + klass.select("#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count") \ + .from("#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}") \ + .where(["#{exclude_self(klass, id)} #{klass.table_name}.#{klass.primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.base_class.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?)", tags_to_find]) \ + .group(group_columns(klass)) \ + .order("count DESC") + end + + private + + def exclude_self(klass, id) + if [self.class.base_class, self.class].include? klass + "#{klass.table_name}.#{klass.primary_key} != #{id} AND" + else + nil + end + end + + def group_columns(klass) + if ActsAsTaggableOn::Tag.using_postgresql? + grouped_column_names_for(klass) + else + "#{klass.table_name}.#{klass.primary_key}" + end + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag.rb new file mode 100644 index 000000000..07bbb6ca7 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag.rb @@ -0,0 +1,99 @@ +module ActsAsTaggableOn + class Tag < ::ActiveRecord::Base + include ActsAsTaggableOn::Utils + + attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity) + + ### ASSOCIATIONS: + + has_many :taggings, :dependent => :destroy, :class_name => 'ActsAsTaggableOn::Tagging' + + ### VALIDATIONS: + + validates_presence_of :name + validates_uniqueness_of :name, :if => :validates_name_uniqueness? + validates_length_of :name, :maximum => 255 + + # monkey patch this method if don't need name uniqueness validation + def validates_name_uniqueness? + true + end + + ### SCOPES: + + def self.named(name) + if ActsAsTaggableOn.strict_case_match + where(["name = #{binary}?", name]) + else + where(["lower(name) = ?", name.downcase]) + end + end + + def self.named_any(list) + if ActsAsTaggableOn.strict_case_match + where(list.map { |tag| sanitize_sql(["name = #{binary}?", tag.to_s.mb_chars]) }.join(" OR ")) + else + where(list.map { |tag| sanitize_sql(["lower(name) = ?", tag.to_s.mb_chars.downcase]) }.join(" OR ")) + end + end + + def self.named_like(name) + where(["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(name)}%"]) + end + + def self.named_like_any(list) + where(list.map { |tag| sanitize_sql(["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(tag.to_s)}%"]) }.join(" OR ")) + end + + ### CLASS METHODS: + + def self.find_or_create_with_like_by_name(name) + if (ActsAsTaggableOn.strict_case_match) + self.find_or_create_all_with_like_by_name([name]).first + else + named_like(name).first || create(:name => name) + end + end + + def self.find_or_create_all_with_like_by_name(*list) + list = [list].flatten + + return [] if list.empty? + + existing_tags = Tag.named_any(list) + + list.map do |tag_name| + comparable_tag_name = comparable_name(tag_name) + existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name } + + existing_tag || Tag.create(:name => tag_name) + end + end + + ### INSTANCE METHODS: + + def ==(object) + super || (object.is_a?(Tag) && name == object.name) + end + + def to_s + name + end + + def count + read_attribute(:count).to_i + end + + class << self + private + + def comparable_name(str) + str.mb_chars.downcase.to_s + end + + def binary + /mysql/ === ActiveRecord::Base.connection_config[:adapter] ? "BINARY " : nil + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag_list.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag_list.rb new file mode 100644 index 000000000..0eb39ebf2 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tag_list.rb @@ -0,0 +1,101 @@ +require 'active_support/core_ext/module/delegation' + +module ActsAsTaggableOn + class TagList < Array + attr_accessor :owner + + def initialize(*args) + add(*args) + end + + ## + # Returns a new TagList using the given tag string. + # + # Example: + # tag_list = TagList.from("One , Two, Three") + # tag_list # ["One", "Two", "Three"] + def self.from(string) + string = string.join(ActsAsTaggableOn.glue) if string.respond_to?(:join) + + new.tap do |tag_list| + string = string.to_s.dup + + # Parse the quoted tags + d = ActsAsTaggableOn.delimiter + d = d.join("|") if d.kind_of?(Array) + string.gsub!(/(\A|#{d})\s*"(.*?)"\s*(#{d}\s*|\z)/) { tag_list << $2; $3 } + string.gsub!(/(\A|#{d})\s*'(.*?)'\s*(#{d}\s*|\z)/) { tag_list << $2; $3 } + + tag_list.add(string.split(Regexp.new d)) + end + end + + ## + # Add tags to the tag_list. Duplicate or blank tags will be ignored. + # Use the :parse option to add an unparsed tag string. + # + # Example: + # tag_list.add("Fun", "Happy") + # tag_list.add("Fun, Happy", :parse => true) + def add(*names) + extract_and_apply_options!(names) + concat(names) + clean! + self + end + + ## + # Remove specific tags from the tag_list. + # Use the :parse option to add an unparsed tag string. + # + # Example: + # tag_list.remove("Sad", "Lonely") + # tag_list.remove("Sad, Lonely", :parse => true) + def remove(*names) + extract_and_apply_options!(names) + delete_if { |name| names.include?(name) } + self + end + + ## + # Transform the tag_list into a tag string suitable for editing in a form. + # The tags are joined with TagList.delimiter and quoted if necessary. + # + # Example: + # tag_list = TagList.new("Round", "Square,Cube") + # tag_list.to_s # 'Round, "Square,Cube"' + def to_s + tags = frozen? ? self.dup : self + tags.send(:clean!) + + tags.map do |name| + d = ActsAsTaggableOn.delimiter + d = Regexp.new d.join("|") if d.kind_of? Array + name.index(d) ? "\"#{name}\"" : name + end.join(ActsAsTaggableOn.glue) + end + + private + + # Remove whitespace, duplicates, and blanks. + def clean! + reject!(&:blank?) + map!(&:strip) + map!{ |tag| tag.mb_chars.downcase.to_s } if ActsAsTaggableOn.force_lowercase + map!(&:parameterize) if ActsAsTaggableOn.force_parameterize + + uniq! + end + + def extract_and_apply_options!(args) + options = args.last.is_a?(Hash) ? args.pop : {} + options.assert_valid_keys :parse + + if options[:parse] + args.map! { |a| self.class.from(a) } + end + + args.flatten! + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/taggable.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/taggable.rb new file mode 100644 index 000000000..a616bcb5d --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/taggable.rb @@ -0,0 +1,105 @@ +module ActsAsTaggableOn + module Taggable + def taggable? + false + end + + ## + # This is an alias for calling acts_as_taggable_on :tags. + # + # Example: + # class Book < ActiveRecord::Base + # acts_as_taggable + # end + def acts_as_taggable + acts_as_taggable_on :tags + end + + ## + # This is an alias for calling acts_as_ordered_taggable_on :tags. + # + # Example: + # class Book < ActiveRecord::Base + # acts_as_ordered_taggable + # end + def acts_as_ordered_taggable + acts_as_ordered_taggable_on :tags + end + + ## + # Make a model taggable on specified contexts. + # + # @param [Array] tag_types An array of taggable contexts + # + # Example: + # class User < ActiveRecord::Base + # acts_as_taggable_on :languages, :skills + # end + def acts_as_taggable_on(*tag_types) + taggable_on(false, tag_types) + end + + + ## + # Make a model taggable on specified contexts + # and preserves the order in which tags are created + # + # @param [Array] tag_types An array of taggable contexts + # + # Example: + # class User < ActiveRecord::Base + # acts_as_ordered_taggable_on :languages, :skills + # end + def acts_as_ordered_taggable_on(*tag_types) + taggable_on(true, tag_types) + end + + private + + # Make a model taggable on specified contexts + # and optionally preserves the order in which tags are created + # + # Seperate methods used above for backwards compatibility + # so that the original acts_as_taggable_on method is unaffected + # as it's not possible to add another arguement to the method + # without the tag_types being enclosed in square brackets + # + # NB: method overridden in core module in order to create tag type + # associations and methods after this logic has executed + # + def taggable_on(preserve_tag_order, *tag_types) + tag_types = tag_types.to_a.flatten.compact.map(&:to_sym) + + if taggable? + self.tag_types = (self.tag_types + tag_types).uniq + self.preserve_tag_order = preserve_tag_order + else + class_attribute :tag_types + self.tag_types = tag_types + class_attribute :preserve_tag_order + self.preserve_tag_order = preserve_tag_order + + class_eval do + has_many :taggings, :as => :taggable, :dependent => :destroy, :class_name => "ActsAsTaggableOn::Tagging" + has_many :base_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag" + + def self.taggable? + true + end + + include ActsAsTaggableOn::Utils + end + end + + # each of these add context-specific methods and must be + # called on each call of taggable_on + include ActsAsTaggableOn::Taggable::Core + include ActsAsTaggableOn::Taggable::Collection + include ActsAsTaggableOn::Taggable::Cache + include ActsAsTaggableOn::Taggable::Ownership + include ActsAsTaggableOn::Taggable::Related + include ActsAsTaggableOn::Taggable::Dirty + end + + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagger.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagger.rb new file mode 100644 index 000000000..bb148e36c --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagger.rb @@ -0,0 +1,76 @@ +module ActsAsTaggableOn + module Tagger + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + ## + # Make a model a tagger. This allows an instance of a model to claim ownership + # of tags. + # + # Example: + # class User < ActiveRecord::Base + # acts_as_tagger + # end + def acts_as_tagger(opts={}) + class_eval do + has_many_with_compatibility :owned_taggings, + opts.merge( + :as => :tagger, + :dependent => :destroy, + :class_name => "ActsAsTaggableOn::Tagging" + ) + + has_many_with_compatibility :owned_tags, + :through => :owned_taggings, + :source => :tag, + :class_name => "ActsAsTaggableOn::Tag", + :uniq => true + end + + include ActsAsTaggableOn::Tagger::InstanceMethods + extend ActsAsTaggableOn::Tagger::SingletonMethods + end + + def is_tagger? + false + end + end + + module InstanceMethods + ## + # Tag a taggable model with tags that are owned by the tagger. + # + # @param taggable The object that will be tagged + # @param [Hash] options An hash with options. Available options are: + # * :with - The tags that you want to + # * :on - The context on which you want to tag + # + # Example: + # @user.tag(@photo, :with => "paris, normandy", :on => :locations) + def tag(taggable, opts={}) + opts.reverse_merge!(:force => true) + skip_save = opts.delete(:skip_save) + return false unless taggable.respond_to?(:is_taggable?) && taggable.is_taggable? + + raise "You need to specify a tag context using :on" unless opts.has_key?(:on) + raise "You need to specify some tags using :with" unless opts.has_key?(:with) + raise "No context :#{opts[:on]} defined in #{taggable.class.to_s}" unless (opts[:force] || taggable.tag_types.include?(opts[:on])) + + taggable.set_owner_tag_list_on(self, opts[:on].to_s, opts[:with]) + taggable.save unless skip_save + end + + def is_tagger? + self.class.is_tagger? + end + end + + module SingletonMethods + def is_tagger? + true + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagging.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagging.rb new file mode 100644 index 000000000..4bcae5a61 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tagging.rb @@ -0,0 +1,34 @@ +module ActsAsTaggableOn + class Tagging < ::ActiveRecord::Base #:nodoc: + attr_accessible :tag, + :tag_id, + :context, + :taggable, + :taggable_type, + :taggable_id, + :tagger, + :tagger_type, + :tagger_id if defined?(ActiveModel::MassAssignmentSecurity) + + belongs_to :tag, :class_name => 'ActsAsTaggableOn::Tag' + belongs_to :taggable, :polymorphic => true + belongs_to :tagger, :polymorphic => true + + validates_presence_of :context + validates_presence_of :tag_id + + validates_uniqueness_of :tag_id, :scope => [ :taggable_type, :taggable_id, :context, :tagger_id, :tagger_type ] + + after_destroy :remove_unused_tags + + private + + def remove_unused_tags + if ActsAsTaggableOn.remove_unused_tags + if tag.taggings.count.zero? + tag.destroy + end + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tags_helper.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tags_helper.rb new file mode 100644 index 000000000..fbbfd0690 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/tags_helper.rb @@ -0,0 +1,15 @@ +module ActsAsTaggableOn + module TagsHelper + # See the README for an example using tag_cloud. + def tag_cloud(tags, classes) + return [] if tags.empty? + + max_count = tags.sort_by(&:count).last.count.to_f + + tags.each do |tag| + index = ((tag.count / max_count) * (classes.size - 1)) + yield tag, classes[index.nan? ? 0 : index.round] + end + end + end +end \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/utils.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/utils.rb new file mode 100644 index 000000000..02f7e07b0 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/utils.rb @@ -0,0 +1,34 @@ +module ActsAsTaggableOn + module Utils + def self.included(base) + + base.send :include, ActsAsTaggableOn::Utils::OverallMethods + base.extend ActsAsTaggableOn::Utils::OverallMethods + end + + module OverallMethods + def using_postgresql? + ::ActiveRecord::Base.connection && ::ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + end + + def using_sqlite? + ::ActiveRecord::Base.connection && ::ActiveRecord::Base.connection.adapter_name == 'SQLite' + end + + def sha_prefix(string) + Digest::SHA1.hexdigest("#{string}#{rand}")[0..6] + end + + private + def like_operator + using_postgresql? ? 'ILIKE' : 'LIKE' + end + + # escape _ and % characters in strings, since these are wildcards in SQL. + def escape_like(str) + str.gsub(/[!%_]/){ |x| '!' + x } + end + end + + end +end diff --git a/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/version.rb b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/version.rb new file mode 100644 index 000000000..16ffef090 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/acts_as_taggable_on/version.rb @@ -0,0 +1,4 @@ +module ActsAsTaggableOn + VERSION = '2.4.2.pre' +end + diff --git a/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/migration_generator.rb b/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/migration_generator.rb new file mode 100644 index 000000000..bb1e69311 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/migration_generator.rb @@ -0,0 +1,39 @@ +require 'rails/generators' +require 'rails/generators/migration' + +module ActsAsTaggableOn + class MigrationGenerator < Rails::Generators::Base + include Rails::Generators::Migration + + desc "Generates migration for Tag and Tagging models" + + def self.orm + Rails::Generators.options[:rails][:orm] + end + + def self.source_root + File.join(File.dirname(__FILE__), 'templates', (orm.to_s unless orm.class.eql?(String)) ) + end + + def self.orm_has_migration? + [:active_record].include? orm + end + + def self.next_migration_number(dirname) + if ActiveRecord::Base.timestamped_migrations + migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i + migration_number += 1 + migration_number.to_s + else + "%.3d" % (current_migration_number(dirname) + 1) + end + end + + def create_migration_file + if self.class.orm_has_migration? + migration_template 'migration.rb', 'db/migrate/acts_as_taggable_on_migration' + end + end + end +end + diff --git a/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb b/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb new file mode 100644 index 000000000..e8b978d96 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb @@ -0,0 +1,30 @@ +class ActsAsTaggableOnMigration < ActiveRecord::Migration + def self.up + create_table :tags do |t| + t.string :name + end + + create_table :taggings do |t| + t.references :tag + + # You should make sure that the column created is + # long enough to store the required class names. + t.references :taggable, :polymorphic => true + t.references :tagger, :polymorphic => true + + # Limit is created to prevent MySQL error on index + # length for MyISAM table type: http://bit.ly/vgW2Ql + t.string :context, :limit => 128 + + t.datetime :created_at + end + + add_index :taggings, :tag_id + add_index :taggings, [:taggable_id, :taggable_type, :context] + end + + def self.down + drop_table :taggings + drop_table :tags + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb new file mode 100644 index 000000000..3c9dc2495 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb @@ -0,0 +1,264 @@ +require 'spec_helper' + +describe "Acts As Taggable On" do + before(:each) do + clean_database! + end + + it "should provide a class method 'taggable?' that is false for untaggable models" do + UntaggableModel.should_not be_taggable + end + + describe "Taggable Method Generation To Preserve Order" do + before(:each) do + clean_database! + TaggableModel.tag_types = [] + TaggableModel.preserve_tag_order = false + TaggableModel.acts_as_ordered_taggable_on(:ordered_tags) + @taggable = TaggableModel.new(:name => "Bob Jones") + end + + it "should respond 'true' to preserve_tag_order?" do + @taggable.class.preserve_tag_order?.should be_true + end + end + + describe "Taggable Method Generation" do + before(:each) do + clean_database! + TaggableModel.tag_types = [] + TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings) + @taggable = TaggableModel.new(:name => "Bob Jones") + end + + it "should respond 'true' to taggable?" do + @taggable.class.should be_taggable + end + + it "should create a class attribute for tag types" do + @taggable.class.should respond_to(:tag_types) + end + + it "should create an instance attribute for tag types" do + @taggable.should respond_to(:tag_types) + end + + it "should have all tag types" do + @taggable.tag_types.should == [:tags, :languages, :skills, :needs, :offerings] + end + + it "should create a class attribute for preserve tag order" do + @taggable.class.should respond_to(:preserve_tag_order?) + end + + it "should create an instance attribute for preserve tag order" do + @taggable.should respond_to(:preserve_tag_order?) + end + + it "should respond 'false' to preserve_tag_order?" do + @taggable.class.preserve_tag_order?.should be_false + end + + it "should generate an association for each tag type" do + @taggable.should respond_to(:tags, :skills, :languages) + end + + it "should add tagged_with and tag_counts to singleton" do + TaggableModel.should respond_to(:tagged_with, :tag_counts) + end + + it "should generate a tag_list accessor/setter for each tag type" do + @taggable.should respond_to(:tag_list, :skill_list, :language_list) + @taggable.should respond_to(:tag_list=, :skill_list=, :language_list=) + end + + it "should generate a tag_list accessor, that includes owned tags, for each tag type" do + @taggable.should respond_to(:all_tags_list, :all_skills_list, :all_languages_list) + end + end + + describe "Reloading" do + it "should save a model instantiated by Model.find" do + taggable = TaggableModel.create!(:name => "Taggable") + found_taggable = TaggableModel.find(taggable.id) + found_taggable.save + end + end + + describe "Matching Contexts" do + it "should find objects with tags of matching contexts" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = TaggableModel.create!(:name => "Taggable 2") + taggable3 = TaggableModel.create!(:name => "Taggable 3") + + taggable1.offering_list = "one, two" + taggable1.save! + + taggable2.need_list = "one, two" + taggable2.save! + + taggable3.offering_list = "one, two" + taggable3.save! + + taggable1.find_matching_contexts(:offerings, :needs).should include(taggable2) + taggable1.find_matching_contexts(:offerings, :needs).should_not include(taggable3) + end + + it "should find other related objects with tags of matching contexts" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = OtherTaggableModel.create!(:name => "Taggable 2") + taggable3 = OtherTaggableModel.create!(:name => "Taggable 3") + + taggable1.offering_list = "one, two" + taggable1.save + + taggable2.need_list = "one, two" + taggable2.save + + taggable3.offering_list = "one, two" + taggable3.save + + taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should include(taggable2) + taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should_not include(taggable3) + end + + it "should not include the object itself in the list of related objects with tags of matching contexts" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = TaggableModel.create!(:name => "Taggable 2") + + taggable1.offering_list = "one, two" + taggable1.need_list = "one, two" + taggable1.save + + taggable2.need_list = "one, two" + taggable2.save + + taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(taggable2) + taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(taggable1) + end + + end + + describe 'Tagging Contexts' do + it 'should eliminate duplicate tagging contexts ' do + TaggableModel.acts_as_taggable_on(:skills, :skills) + TaggableModel.tag_types.freq[:skills].should_not == 3 + end + + it "should not contain embedded/nested arrays" do + TaggableModel.acts_as_taggable_on([:array], [:array]) + TaggableModel.tag_types.freq[[:array]].should == 0 + end + + it "should _flatten_ the content of arrays" do + TaggableModel.acts_as_taggable_on([:array], [:array]) + TaggableModel.tag_types.freq[:array].should == 1 + end + + it "should not raise an error when passed nil" do + lambda { + TaggableModel.acts_as_taggable_on() + }.should_not raise_error + end + + it "should not raise an error when passed [nil]" do + lambda { + TaggableModel.acts_as_taggable_on([nil]) + }.should_not raise_error + end + end + + context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do + describe 'caching' do + before { @taggable = OtherCachedModel.new(:name => "John Smith") } + subject { @taggable } + + it { should respond_to(:save_cached_tag_list) } + its(:cached_language_list) { should be_blank } + its(:cached_status_list) { should be_blank } + its(:cached_glass_list) { should be_blank } + + context 'language taggings cache after update' do + before { @taggable.update_attributes(:language_list => 'ruby, .net') } + subject { @taggable } + + its(:language_list) { should == ['ruby', '.net']} + its(:cached_language_list) { should == 'ruby, .net' } # passes + its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@language_list' : :@language_list)) } + end + + context 'status taggings cache after update' do + before { @taggable.update_attributes(:status_list => 'happy, married') } + subject { @taggable } + + its(:status_list) { should == ['happy', 'married'] } + its(:cached_status_list) { should == 'happy, married' } # fails + its(:cached_status_list) { should_not == '' } # fails, is blank + its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@status_list' : :@status_list)) } + its(:instance_variables) { should_not include((RUBY_VERSION < '1.9' ? '@statu_list' : :@statu_list)) } # fails, note: one "s" + + end + + context 'glass taggings cache after update' do + before do + @taggable.update_attributes(:glass_list => 'rectangle, aviator') + end + + subject { @taggable } + its(:glass_list) { should == ['rectangle', 'aviator'] } + its(:cached_glass_list) { should == 'rectangle, aviator' } # fails + its(:cached_glass_list) { should_not == '' } # fails, is blank + if RUBY_VERSION < '1.9' + its(:instance_variables) { should include('@glass_list') } + its(:instance_variables) { should_not include('@glas_list') } # fails, note: one "s" + else + its(:instance_variables) { should include(:@glass_list) } + its(:instance_variables) { should_not include(:@glas_list) } # fails, note: one "s" + end + + end + end + end + + describe "taggings" do + before(:each) do + @taggable = TaggableModel.new(:name => "Art Kram") + end + + it 'should return [] taggings' do + @taggable.taggings.should == [] + end + end + + describe "@@remove_unused_tags" do + before do + @taggable = TaggableModel.create(:name => "Bob Jones") + @tag = ActsAsTaggableOn::Tag.create(:name => "awesome") + + @tagging = ActsAsTaggableOn::Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags') + end + + context "if set to true" do + before do + ActsAsTaggableOn.remove_unused_tags = true + end + + it "should remove unused tags after removing taggings" do + @tagging.destroy + ActsAsTaggableOn::Tag.find_by_name("awesome").should be_nil + end + end + + context "if set to false" do + before do + ActsAsTaggableOn.remove_unused_tags = false + end + + it "should not remove unused tags after removing taggings" do + @tagging.destroy + ActsAsTaggableOn::Tag.find_by_name("awesome").should == @tag + end + end + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_tagger_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_tagger_spec.rb new file mode 100644 index 000000000..9591fcba3 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/acts_as_tagger_spec.rb @@ -0,0 +1,114 @@ +require 'spec_helper' + +describe "acts_as_tagger" do + before(:each) do + clean_database! + end + + describe "Tagger Method Generation" do + before(:each) do + @tagger = User.new + end + + it "should add #is_tagger? query method to the class-side" do + User.should respond_to(:is_tagger?) + end + + it "should return true from the class-side #is_tagger?" do + User.is_tagger?.should be_true + end + + it "should return false from the base #is_tagger?" do + ActiveRecord::Base.is_tagger?.should be_false + end + + it "should add #is_tagger? query method to the singleton" do + @tagger.should respond_to(:is_tagger?) + end + + it "should add #tag method on the instance-side" do + @tagger.should respond_to(:tag) + end + + it "should generate an association for #owned_taggings and #owned_tags" do + @tagger.should respond_to(:owned_taggings, :owned_tags) + end + end + + describe "#tag" do + context 'when called with a non-existent tag context' do + before(:each) do + @tagger = User.new + @taggable = TaggableModel.new(:name=>"Richard Prior") + end + + it "should by default not throw an exception " do + @taggable.tag_list_on(:foo).should be_empty + lambda { + @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo) + }.should_not raise_error + end + + it 'should by default create the tag context on-the-fly' do + @taggable.tag_list_on(:here_ond_now).should be_empty + @tagger.tag(@taggable, :with=>'that', :on => :here_ond_now) + @taggable.tag_list_on(:here_ond_now).should_not include('that') + @taggable.all_tags_list_on(:here_ond_now).should include('that') + end + + it "should show all the tag list when both public and owned tags exist" do + @taggable.tag_list = 'ruby, python' + @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags) + @taggable.all_tags_on(:tags).map(&:name).sort.should == %w(ruby python java lisp).sort + end + + it "should not add owned tags to the common list" do + @taggable.tag_list = 'ruby, python' + @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags) + @taggable.tag_list.should == %w(ruby python) + @tagger.tag(@taggable, :with => '', :on => :tags) + @taggable.tag_list.should == %w(ruby python) + end + + it "should throw an exception when the default is over-ridden" do + @taggable.tag_list_on(:foo_boo).should be_empty + lambda { + @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false) + }.should raise_error + end + + it "should not create the tag context on-the-fly when the default is over-ridden" do + @taggable.tag_list_on(:foo_boo).should be_empty + @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false) rescue + @taggable.tag_list_on(:foo_boo).should be_empty + end + end + + describe "when called by multiple tagger's" do + before(:each) do + @user_x = User.create(:name => "User X") + @user_y = User.create(:name => "User Y") + @taggable = TaggableModel.create(:name => 'acts_as_taggable_on', :tag_list => 'plugin') + + @user_x.tag(@taggable, :with => 'ruby, rails', :on => :tags) + @user_y.tag(@taggable, :with => 'ruby, plugin', :on => :tags) + + @user_y.tag(@taggable, :with => '', :on => :tags) + @user_y.tag(@taggable, :with => '', :on => :tags) + end + + it "should delete owned tags" do + @user_y.owned_tags.should == [] + end + + it "should not delete other taggers tags" do + @user_x.owned_tags.should have(2).items + end + + it "should not delete original tags" do + @taggable.all_tags_list_on(:tags).should include('plugin') + end + end + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/caching_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/caching_spec.rb new file mode 100644 index 000000000..5aab999d9 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/caching_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe "Acts As Taggable On" do + + before(:each) do + clean_database! + end + + describe 'Caching' do + before(:each) do + @taggable = CachedModel.new(:name => "Bob Jones") + @another_taggable = OtherCachedModel.new(:name => "John Smith") + end + + it "should add saving of tag lists and cached tag lists to the instance" do + @taggable.should respond_to(:save_cached_tag_list) + @another_taggable.should respond_to(:save_cached_tag_list) + + @taggable.should respond_to(:save_tags) + end + + it "should add cached tag lists to the instance if cached column is not present" do + TaggableModel.new(:name => "Art Kram").should_not respond_to(:save_cached_tag_list) + end + + it "should generate a cached column checker for each tag type" do + CachedModel.should respond_to(:caching_tag_list?) + OtherCachedModel.should respond_to(:caching_language_list?) + end + + it 'should not have cached tags' do + @taggable.cached_tag_list.should be_blank + @another_taggable.cached_language_list.should be_blank + end + + it 'should cache tags' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable.cached_tag_list.should == 'awesome, epic' + + @another_taggable.update_attributes(:language_list => 'ruby, .net') + @another_taggable.cached_language_list.should == 'ruby, .net' + end + + it 'should keep the cache' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable = CachedModel.find(@taggable) + @taggable.save! + @taggable.cached_tag_list.should == 'awesome, epic' + end + + it 'should update the cache' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable.update_attributes(:tag_list => 'awesome') + @taggable.cached_tag_list.should == 'awesome' + end + + it 'should remove the cache' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable.update_attributes(:tag_list => '') + @taggable.cached_tag_list.should be_blank + end + + it 'should have a tag list' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable = CachedModel.find(@taggable.id) + @taggable.tag_list.sort.should == %w(awesome epic).sort + end + + it 'should keep the tag list' do + @taggable.update_attributes(:tag_list => 'awesome, epic') + @taggable = CachedModel.find(@taggable.id) + @taggable.save! + @taggable.tag_list.sort.should == %w(awesome epic).sort + end + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/related_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/related_spec.rb new file mode 100644 index 000000000..acbc8fd5e --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/related_spec.rb @@ -0,0 +1,143 @@ +require 'spec_helper' + +describe "Acts As Taggable On" do + before(:each) do + clean_database! + end + + describe "Related Objects" do + it "should find related objects based on tag names on context" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = TaggableModel.create!(:name => "Taggable 2") + taggable3 = TaggableModel.create!(:name => "Taggable 3") + + taggable1.tag_list = "one, two" + taggable1.save + + taggable2.tag_list = "three, four" + taggable2.save + + taggable3.tag_list = "one, four" + taggable3.save + + taggable1.find_related_tags.should include(taggable3) + taggable1.find_related_tags.should_not include(taggable2) + end + + it "finds related tags for ordered taggable on" do + taggable1 = OrderedTaggableModel.create!(:name => "Taggable 1") + taggable2 = OrderedTaggableModel.create!(:name => "Taggable 2") + taggable3 = OrderedTaggableModel.create!(:name => "Taggable 3") + + taggable1.colour_list = "one, two" + taggable1.save + + taggable2.colour_list = "three, four" + taggable2.save + + taggable3.colour_list = "one, four" + taggable3.save + + taggable1.find_related_colours.should include(taggable3) + taggable1.find_related_colours.should_not include(taggable2) + end + + it "should find related objects based on tag names on context - non standard id" do + taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1") + taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2") + taggable3 = NonStandardIdTaggableModel.create!(:name => "Taggable 3") + + taggable1.tag_list = "one, two" + taggable1.save + + taggable2.tag_list = "three, four" + taggable2.save + + taggable3.tag_list = "one, four" + taggable3.save + + taggable1.find_related_tags.should include(taggable3) + taggable1.find_related_tags.should_not include(taggable2) + end + + it "should find other related objects based on tag names on context" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = OtherTaggableModel.create!(:name => "Taggable 2") + taggable3 = OtherTaggableModel.create!(:name => "Taggable 3") + + taggable1.tag_list = "one, two" + taggable1.save + + taggable2.tag_list = "three, four" + taggable2.save + + taggable3.tag_list = "one, four" + taggable3.save + + taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3) + taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2) + end + + it "should not include the object itself in the list of related objects" do + taggable1 = TaggableModel.create!(:name => "Taggable 1") + taggable2 = TaggableModel.create!(:name => "Taggable 2") + + taggable1.tag_list = "one" + taggable1.save + + taggable2.tag_list = "one, two" + taggable2.save + + taggable1.find_related_tags.should include(taggable2) + taggable1.find_related_tags.should_not include(taggable1) + end + + it "should not include the object itself in the list of related objects - non standard id" do + taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1") + taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2") + + taggable1.tag_list = "one" + taggable1.save + + taggable2.tag_list = "one, two" + taggable2.save + + taggable1.find_related_tags.should include(taggable2) + taggable1.find_related_tags.should_not include(taggable1) + end + + context "Ignored Tags" do + let(:taggable1) { TaggableModel.create!(:name => "Taggable 1") } + let(:taggable2) { TaggableModel.create!(:name => "Taggable 2") } + let(:taggable3) { TaggableModel.create!(:name => "Taggable 3") } + before(:each) do + taggable1.tag_list = "one, two, four" + taggable1.save + + taggable2.tag_list = "two, three" + taggable2.save + + taggable3.tag_list = "one, three" + taggable3.save + end + it "should not include ignored tags in related search" do + taggable1.find_related_tags(:ignore => 'two').should_not include(taggable2) + taggable1.find_related_tags(:ignore => 'two').should include(taggable3) + end + + it "should accept array of ignored tags" do + taggable4 = TaggableModel.create!(:name => "Taggable 4") + taggable4.tag_list = "four" + taggable4.save + + taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable2) + taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable4) + end + + it "should accept symbols as ignored tags" do + taggable1.find_related_tags(:ignore => :two).should_not include(taggable2) + end + end + + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/single_table_inheritance_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/single_table_inheritance_spec.rb new file mode 100644 index 000000000..4d8ca57b8 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/single_table_inheritance_spec.rb @@ -0,0 +1,187 @@ +require 'spec_helper' + +describe "Single Table Inheritance" do + + before(:each) do + clean_database! + end + + let(:taggable) { TaggableModel.new(:name => "taggable model") } + + let(:inheriting_model) { InheritingTaggableModel.new(:name => "Inheriting Taggable Model") } + let(:altered_inheriting) { AlteredInheritingTaggableModel.new(:name => "Altered Inheriting Model") } + + 1.upto(4) do |n| + let(:"inheriting_#{n}") { InheritingTaggableModel.new(:name => "Inheriting Model #{n}") } + end + + let(:student) { Student.create! } + + describe "tag contexts" do + it "should pass on to STI-inherited models" do + inheriting_model.should respond_to(:tag_list, :skill_list, :language_list) + altered_inheriting.should respond_to(:tag_list, :skill_list, :language_list) + end + + it "should pass on to altered STI models" do + altered_inheriting.should respond_to(:part_list) + end + end + + context "matching contexts" do + + before do + inheriting_1.offering_list = "one, two" + inheriting_1.need_list = "one, two" + inheriting_1.save! + + inheriting_2.need_list = "one, two" + inheriting_2.save! + + inheriting_3.offering_list = "one, two" + inheriting_3.save! + + inheriting_4.tag_list = "one, two, three, four" + inheriting_4.save! + + taggable.need_list = "one, two" + taggable.save! + end + + it "should find objects with tags of matching contexts" do + inheriting_1.find_matching_contexts(:offerings, :needs).should include(inheriting_2) + inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_3) + inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_4) + inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(taggable) + + inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(inheriting_2) + inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_3) + inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_4) + inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(taggable) + end + + it "should not include the object itself in the list of related objects with tags of matching contexts" do + inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_1) + inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs).should_not include(inheriting_1) + inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_1) + end + end + + context "find related tags" do + before do + inheriting_1.tag_list = "one, two" + inheriting_1.save + + inheriting_2.tag_list = "three, four" + inheriting_2.save + + inheriting_3.tag_list = "one, four" + inheriting_3.save + + taggable.tag_list = "one, two, three, four" + taggable.save + end + + it "should find related objects based on tag names on context" do + inheriting_1.find_related_tags.should include(inheriting_3) + inheriting_1.find_related_tags.should_not include(inheriting_2) + inheriting_1.find_related_tags.should_not include(taggable) + + inheriting_1.find_related_tags_for(TaggableModel).should include(inheriting_3) + inheriting_1.find_related_tags_for(TaggableModel).should_not include(inheriting_2) + inheriting_1.find_related_tags_for(TaggableModel).should include(taggable) + end + + it "should not include the object itself in the list of related objects" do + inheriting_1.find_related_tags.should_not include(inheriting_1) + inheriting_1.find_related_tags_for(InheritingTaggableModel).should_not include(inheriting_1) + inheriting_1.find_related_tags_for(TaggableModel).should_not include(inheriting_1) + end + end + + describe "tag list" do + before do + @inherited_same = InheritingTaggableModel.new(:name => "inherited same") + @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different") + end + + it "should be able to save tags for inherited models" do + inheriting_model.tag_list = "bob, kelso" + inheriting_model.save + InheritingTaggableModel.tagged_with("bob").first.should == inheriting_model + end + + it "should find STI tagged models on the superclass" do + inheriting_model.tag_list = "bob, kelso" + inheriting_model.save + TaggableModel.tagged_with("bob").first.should == inheriting_model + end + + it "should be able to add on contexts only to some subclasses" do + altered_inheriting.part_list = "fork, spoon" + altered_inheriting.save + InheritingTaggableModel.tagged_with("fork", :on => :parts).should be_empty + AlteredInheritingTaggableModel.tagged_with("fork", :on => :parts).first.should == altered_inheriting + end + + it "should have different tag_counts_on for inherited models" do + inheriting_model.tag_list = "bob, kelso" + inheriting_model.save! + altered_inheriting.tag_list = "fork, spoon" + altered_inheriting.save! + + InheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso) + AlteredInheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon) + TaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon) + end + + it "should have different tags_on for inherited models" do + inheriting_model.tag_list = "bob, kelso" + inheriting_model.save! + altered_inheriting.tag_list = "fork, spoon" + altered_inheriting.save! + + InheritingTaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso) + AlteredInheritingTaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon) + TaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon) + end + + it 'should store same tag without validation conflict' do + taggable.tag_list = 'one' + taggable.save! + + inheriting_model.tag_list = 'one' + inheriting_model.save! + + inheriting_model.update_attributes! :name => 'foo' + end + end + + describe "ownership" do + it "should have taggings" do + student.tag(taggable, :with=>'ruby,scheme', :on=>:tags) + student.owned_taggings.should have(2).tags + end + + it "should have tags" do + student.tag(taggable, :with=>'ruby,scheme', :on=>:tags) + student.owned_tags.should have(2).tags + end + + it "should return tags for the inheriting tagger" do + student.tag(taggable, :with => 'ruby, scheme', :on => :tags) + taggable.tags_from(student).should match_array(%w(ruby scheme)) + end + + it "returns owner tags on the tagger" do + student.tag(taggable, :with => 'ruby, scheme', :on => :tags) + taggable.owner_tags_on(student, :tags).should have(2).tags + end + + it "should scope objects returned by tagged_with by owners" do + student.tag(taggable, :with => 'ruby, scheme', :on => :tags) + TaggableModel.tagged_with(%w(ruby scheme), :owned_by => student).should have(1).tag + end + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_list_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_list_spec.rb new file mode 100644 index 000000000..cb8afb312 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_list_spec.rb @@ -0,0 +1,126 @@ +# encoding: utf-8 +require 'spec_helper' + +describe ActsAsTaggableOn::TagList do + let(:tag_list) { ActsAsTaggableOn::TagList.new("awesome","radical") } + + it { should be_kind_of Array } + + it "#from should return empty array if empty array is passed" do + ActsAsTaggableOn::TagList.from([]).should be_empty + end + + describe "#add" do + it "should be able to be add a new tag word" do + tag_list.add("cool") + tag_list.include?("cool").should be_true + end + + it "should be able to add delimited lists of words" do + tag_list.add("cool, wicked", :parse => true) + tag_list.should include("cool", "wicked") + end + + it "should be able to add delimited list of words with quoted delimiters" do + tag_list.add("'cool, wicked', \"really cool, really wicked\"", :parse => true) + tag_list.should include("cool, wicked", "really cool, really wicked") + end + + it "should be able to handle other uses of quotation marks correctly" do + tag_list.add("john's cool car, mary's wicked toy", :parse => true) + tag_list.should include("john's cool car", "mary's wicked toy") + end + + it "should be able to add an array of words" do + tag_list.add(["cool", "wicked"], :parse => true) + tag_list.should include("cool", "wicked") + end + + it "should quote escape tags with commas in them" do + tag_list.add("cool","rad,bodacious") + tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\"" + end + + end + + describe "#remove" do + it "should be able to remove words" do + tag_list.remove("awesome") + tag_list.should_not include("awesome") + end + + it "should be able to remove delimited lists of words" do + tag_list.remove("awesome, radical", :parse => true) + tag_list.should be_empty + end + + it "should be able to remove an array of words" do + tag_list.remove(["awesome", "radical"], :parse => true) + tag_list.should be_empty + end + end + + describe "#to_s" do + it "should give a delimited list of words when converted to string" do + tag_list.to_s.should == "awesome, radical" + end + + it "should be able to call to_s on a frozen tag list" do + tag_list.freeze + lambda { tag_list.add("cool","rad,bodacious") }.should raise_error + lambda { tag_list.to_s }.should_not raise_error + end + end + + describe "cleaning" do + it "should parameterize if force_parameterize is set to true" do + ActsAsTaggableOn.force_parameterize = true + tag_list = ActsAsTaggableOn::TagList.new("awesome()","radical)(cc") + + tag_list.to_s.should == "awesome, radical-cc" + ActsAsTaggableOn.force_parameterize = false + end + + it "should lowercase if force_lowercase is set to true" do + ActsAsTaggableOn.force_lowercase = true + + tag_list = ActsAsTaggableOn::TagList.new("aweSomE","RaDicaL","Entrée") + tag_list.to_s.should == "awesome, radical, entrée" + + ActsAsTaggableOn.force_lowercase = false + end + + end + + describe "Multiple Delimiter" do + before do + @old_delimiter = ActsAsTaggableOn.delimiter + end + + after do + ActsAsTaggableOn.delimiter = @old_delimiter + end + + it "should separate tags by delimiters" do + ActsAsTaggableOn.delimiter = [',', ' ', '\|'] + tag_list = ActsAsTaggableOn::TagList.from "cool, data|I have" + tag_list.to_s.should == 'cool, data, I, have' + end + + it "should escape quote" do + ActsAsTaggableOn.delimiter = [',', ' ', '\|'] + tag_list = ActsAsTaggableOn::TagList.from "'I have'|cool, data" + tag_list.to_s.should == '"I have", cool, data' + + tag_list = ActsAsTaggableOn::TagList.from '"I, have"|cool, data' + tag_list.to_s.should == '"I, have", cool, data' + end + + it "should work for utf8 delimiter and long delimiter" do + ActsAsTaggableOn.delimiter = [',', 'çš„', 'å¯èƒ½æ˜¯'] + tag_list = ActsAsTaggableOn::TagList.from "我的东西å¯èƒ½æ˜¯ä¸è§äº†ï¼Œè¿˜å¥½æœ‰å¤‡ä»½" + tag_list.to_s.should == "我, 东西, ä¸è§äº†ï¼Œ 还好有备份" + end + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_spec.rb new file mode 100644 index 000000000..74c9d4550 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tag_spec.rb @@ -0,0 +1,211 @@ +# encoding: utf-8 +require 'spec_helper' + +describe ActsAsTaggableOn::Tag do + before(:each) do + clean_database! + @tag = ActsAsTaggableOn::Tag.new + @user = TaggableModel.create(:name => "Pablo") + end + + describe "named like any" do + before(:each) do + ActsAsTaggableOn::Tag.create(:name => "Awesome") + ActsAsTaggableOn::Tag.create(:name => "awesome") + ActsAsTaggableOn::Tag.create(:name => "epic") + end + + it "should find both tags" do + ActsAsTaggableOn::Tag.named_like_any(["awesome", "epic"]).should have(3).items + end + end + + describe "find or create by name" do + before(:each) do + @tag.name = "awesome" + @tag.save + end + + it "should find by name" do + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("awesome").should == @tag + end + + it "should find by name case insensitive" do + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("AWESOME").should == @tag + end + + it "should create by name" do + lambda { + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("epic") + }.should change(ActsAsTaggableOn::Tag, :count).by(1) + end + end + + unless ActsAsTaggableOn::Tag.using_sqlite? + describe "find or create by unicode name" do + before(:each) do + @tag.name = "привет" + @tag.save + end + + it "should find by name" do + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("привет").should == @tag + end + + it "should find by name case insensitive" do + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("ПРИВЕТ").should == @tag + end + end + end + + describe "find or create all by any name" do + before(:each) do + @tag.name = "awesome" + @tag.save + end + + it "should find by name" do + ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name("awesome").should == [@tag] + end + + it "should find by name case insensitive" do + ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name("AWESOME").should == [@tag] + end + + it "should create by name" do + lambda { + ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name("epic") + }.should change(ActsAsTaggableOn::Tag, :count).by(1) + end + + it "should find or create by name" do + lambda { + ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name("awesome", "epic").map(&:name).should == ["awesome", "epic"] + }.should change(ActsAsTaggableOn::Tag, :count).by(1) + end + + it "should return an empty array if no tags are specified" do + ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name([]).should == [] + end + end + + it "should require a name" do + @tag.valid? + + @tag.errors[:name].should == ["can't be blank"] + + @tag.name = "something" + @tag.valid? + + @tag.errors[:name].should == [] + end + + it "should limit the name length to 255 or less characters" do + @tag.name = "fgkgnkkgjymkypbuozmwwghblmzpqfsgjasflblywhgkwndnkzeifalfcpeaeqychjuuowlacmuidnnrkprgpcpybarbkrmziqihcrxirlokhnzfvmtzixgvhlxzncyywficpraxfnjptxxhkqmvicbcdcynkjvziefqzyndxkjmsjlvyvbwraklbalykyxoliqdlreeykuphdtmzfdwpphmrqvwvqffojkqhlzvinqajsxbszyvrqqyzusxranr" + @tag.valid? + @tag.errors[:name].should == ["is too long (maximum is 255 characters)"] + + @tag.name = "fgkgnkkgjymkypbuozmwwghblmzpqfsgjasflblywhgkwndnkzeifalfcpeaeqychjuuowlacmuidnnrkprgpcpybarbkrmziqihcrxirlokhnzfvmtzixgvhlxzncyywficpraxfnjptxxhkqmvicbcdcynkjvziefqzyndxkjmsjlvyvbwraklbalykyxoliqdlreeykuphdtmzfdwpphmrqvwvqffojkqhlzvinqajsxbszyvrqqyzusxran" + @tag.valid? + @tag.errors[:name].should == [] + end + + it "should equal a tag with the same name" do + @tag.name = "awesome" + new_tag = ActsAsTaggableOn::Tag.new(:name => "awesome") + new_tag.should == @tag + end + + it "should return its name when to_s is called" do + @tag.name = "cool" + @tag.to_s.should == "cool" + end + + it "have named_scope named(something)" do + @tag.name = "cool" + @tag.save! + ActsAsTaggableOn::Tag.named('cool').should include(@tag) + end + + it "have named_scope named_like(something)" do + @tag.name = "cool" + @tag.save! + @another_tag = ActsAsTaggableOn::Tag.create!(:name => "coolip") + ActsAsTaggableOn::Tag.named_like('cool').should include(@tag, @another_tag) + end + + describe "escape wildcard symbols in like requests" do + before(:each) do + @tag.name = "cool" + @tag.save + @another_tag = ActsAsTaggableOn::Tag.create!(:name => "coo%") + @another_tag2 = ActsAsTaggableOn::Tag.create!(:name => "coolish") + end + + it "return escaped result when '%' char present in tag" do + ActsAsTaggableOn::Tag.named_like('coo%').should_not include(@tag) + ActsAsTaggableOn::Tag.named_like('coo%').should include(@another_tag) + end + + end + + describe "when using strict_case_match" do + before do + ActsAsTaggableOn.strict_case_match = true + @tag.name = "awesome" + @tag.save! + end + + after do + ActsAsTaggableOn.strict_case_match = false + end + + it "should find by name" do + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("awesome").should == @tag + end + + it "should find by name case sensitively" do + expect { + ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("AWESOME") + }.to change(ActsAsTaggableOn::Tag, :count) + + ActsAsTaggableOn::Tag.last.name.should == "AWESOME" + end + + it "should have a named_scope named(something) that matches exactly" do + uppercase_tag = ActsAsTaggableOn::Tag.create(:name => "Cool") + @tag.name = "cool" + @tag.save! + + ActsAsTaggableOn::Tag.named('cool').should include(@tag) + ActsAsTaggableOn::Tag.named('cool').should_not include(uppercase_tag) + end + end + + describe "name uniqeness validation" do + let(:duplicate_tag) { ActsAsTaggableOn::Tag.new(:name => 'ror') } + + before { ActsAsTaggableOn::Tag.create(:name => 'ror') } + + context "when don't need unique names" do + it "should not run uniqueness validation" do + duplicate_tag.stub(:validates_name_uniqueness?).and_return(false) + duplicate_tag.save + duplicate_tag.should be_persisted + end + end + + context "when do need unique names" do + it "should run uniqueness validation" do + duplicate_tag.should_not be_valid + end + + it "add error to name" do + duplicate_tag.save + + duplicate_tag.should have(1).errors + duplicate_tag.errors.messages[:name].should include('has already been taken') + end + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/taggable_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/taggable_spec.rb new file mode 100644 index 000000000..bb919df6a --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/taggable_spec.rb @@ -0,0 +1,623 @@ +require 'spec_helper' + +describe "Taggable To Preserve Order" do + before(:each) do + clean_database! + @taggable = OrderedTaggableModel.new(:name => "Bob Jones") + end + + it "should have tag types" do + [:tags, :colours].each do |type| + OrderedTaggableModel.tag_types.should include type + end + + @taggable.tag_types.should == OrderedTaggableModel.tag_types + end + + it "should have tag associations" do + [:tags, :colours].each do |type| + @taggable.respond_to?(type).should be_true + @taggable.respond_to?("#{type.to_s.singularize}_taggings").should be_true + end + end + + # it "should have tag associations ordered by id" do + # [:tags, :colours].each do |type| + # OrderedTaggableModel.reflect_on_association(type).options[:order].should include('id') + # OrderedTaggableModel.reflect_on_association("#{type.to_s.singularize}_taggings".to_sym).options[:order].should include('id') + # end + # end + + it "should have tag methods" do + [:tags, :colours].each do |type| + @taggable.respond_to?("#{type.to_s.singularize}_list").should be_true + @taggable.respond_to?("#{type.to_s.singularize}_list=").should be_true + @taggable.respond_to?("all_#{type.to_s}_list").should be_true + end + end + + it "should return tag list in the order the tags were created" do + # create + @taggable.tag_list = "rails, ruby, css" + @taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true + + lambda { + @taggable.save + }.should change(ActsAsTaggableOn::Tag, :count).by(3) + + @taggable.reload + @taggable.tag_list.should == %w(rails ruby css) + + # update + @taggable.tag_list = "pow, ruby, rails" + @taggable.save + + @taggable.reload + @taggable.tag_list.should == %w(pow ruby rails) + + # update with no change + @taggable.tag_list = "pow, ruby, rails" + @taggable.save + + @taggable.reload + @taggable.tag_list.should == %w(pow ruby rails) + + # update to clear tags + @taggable.tag_list = "" + @taggable.save + + @taggable.reload + @taggable.tag_list.should == [] + end + + it "should return tag objects in the order the tags were created" do + # create + @taggable.tag_list = "pow, ruby, rails" + @taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true + + lambda { + @taggable.save + }.should change(ActsAsTaggableOn::Tag, :count).by(3) + + @taggable.reload + @taggable.tags.map{|t| t.name}.should == %w(pow ruby rails) + + # update + @taggable.tag_list = "rails, ruby, css, pow" + @taggable.save + + @taggable.reload + @taggable.tags.map{|t| t.name}.should == %w(rails ruby css pow) + end + + it "should return tag objects in tagging id order" do + # create + @taggable.tag_list = "pow, ruby, rails" + @taggable.save + + @taggable.reload + ids = @taggable.tags.map{|t| t.taggings.first.id} + ids.should == ids.sort + + # update + @taggable.tag_list = "rails, ruby, css, pow" + @taggable.save + + @taggable.reload + ids = @taggable.tags.map{|t| t.taggings.first.id} + ids.should == ids.sort + end +end + +describe "Taggable" do + before(:each) do + clean_database! + @taggable = TaggableModel.new(:name => "Bob Jones") + @taggables = [@taggable, TaggableModel.new(:name => "John Doe")] + end + + it "should have tag types" do + [:tags, :languages, :skills, :needs, :offerings].each do |type| + TaggableModel.tag_types.should include type + end + + @taggable.tag_types.should == TaggableModel.tag_types + end + + it "should have tag_counts_on" do + TaggableModel.tag_counts_on(:tags).should be_empty + + @taggable.tag_list = ["awesome", "epic"] + @taggable.save + + TaggableModel.tag_counts_on(:tags).length.should == 2 + @taggable.tag_counts_on(:tags).length.should == 2 + end + + it "should have tags_on" do + TaggableModel.tags_on(:tags).should be_empty + + @taggable.tag_list = ["awesome", "epic"] + @taggable.save + + TaggableModel.tags_on(:tags).length.should == 2 + @taggable.tags_on(:tags).length.should == 2 + end + + it "should return [] right after create" do + blank_taggable = TaggableModel.new(:name => "Bob Jones") + blank_taggable.tag_list.should == [] + end + + it "should be able to create tags" do + @taggable.skill_list = "ruby, rails, css" + @taggable.instance_variable_get("@skill_list").instance_of?(ActsAsTaggableOn::TagList).should be_true + + lambda { + @taggable.save + }.should change(ActsAsTaggableOn::Tag, :count).by(3) + + @taggable.reload + @taggable.skill_list.sort.should == %w(ruby rails css).sort + end + + it "should be able to create tags through the tag list directly" do + @taggable.tag_list_on(:test).add("hello") + @taggable.tag_list_cache_on(:test).should_not be_empty + @taggable.tag_list_on(:test).should == ["hello"] + + @taggable.save + @taggable.save_tags + + @taggable.reload + @taggable.tag_list_on(:test).should == ["hello"] + end + + it "should differentiate between contexts" do + @taggable.skill_list = "ruby, rails, css" + @taggable.tag_list = "ruby, bob, charlie" + @taggable.save + @taggable.reload + @taggable.skill_list.should include("ruby") + @taggable.skill_list.should_not include("bob") + end + + it "should be able to remove tags through list alone" do + @taggable.skill_list = "ruby, rails, css" + @taggable.save + @taggable.reload + @taggable.should have(3).skills + @taggable.skill_list = "ruby, rails" + @taggable.save + @taggable.reload + @taggable.should have(2).skills + end + + it "should be able to select taggables by subset of tags using ActiveRelation methods" do + @taggables[0].tag_list = "bob" + @taggables[1].tag_list = "charlie" + @taggables[0].skill_list = "ruby" + @taggables[1].skill_list = "css" + @taggables.each{|taggable| taggable.save} + + @found_taggables_by_tag = TaggableModel.joins(:tags).where(:tags => {:name => ["bob"]}) + @found_taggables_by_skill = TaggableModel.joins(:skills).where(:tags => {:name => ["ruby"]}) + + @found_taggables_by_tag.should include @taggables[0] + @found_taggables_by_tag.should_not include @taggables[1] + @found_taggables_by_skill.should include @taggables[0] + @found_taggables_by_skill.should_not include @taggables[1] + end + + it "should be able to find by tag" do + @taggable.skill_list = "ruby, rails, css" + @taggable.save + + TaggableModel.tagged_with("ruby").first.should == @taggable + end + + it "should be able to find by tag with context" do + @taggable.skill_list = "ruby, rails, css" + @taggable.tag_list = "bob, charlie" + @taggable.save + + TaggableModel.tagged_with("ruby").first.should == @taggable + TaggableModel.tagged_with("ruby, css").first.should == @taggable + TaggableModel.tagged_with("bob", :on => :skills).first.should_not == @taggable + TaggableModel.tagged_with("bob", :on => :tags).first.should == @taggable + end + + it "should not care about case" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby") + frank = TaggableModel.create(:name => "Frank", :tag_list => "Ruby") + + ActsAsTaggableOn::Tag.all.size.should == 1 + TaggableModel.tagged_with("ruby").to_a.should == TaggableModel.tagged_with("Ruby").to_a + end + + it "should be able to get tag counts on model as a whole" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + TaggableModel.tag_counts.should_not be_empty + TaggableModel.skill_counts.should_not be_empty + end + + it "should be able to get all tag counts on model as whole" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + + TaggableModel.all_tag_counts.should_not be_empty + TaggableModel.all_tag_counts(:order => 'tags.id').first.count.should == 3 # ruby + end + + it "should be able to get all tags on model as whole" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + + TaggableModel.all_tags.should_not be_empty + TaggableModel.all_tags(:order => 'tags.id').first.name.should == "ruby" + end + + it "should be able to use named scopes to chain tag finds by any tags by context" do + bob = TaggableModel.create(:name => "Bob", :need_list => "rails", :offering_list => "c++") + frank = TaggableModel.create(:name => "Frank", :need_list => "css", :offering_list => "css") + steve = TaggableModel.create(:name => 'Steve', :need_list => "c++", :offering_list => "java") + + # Let's only find those who need rails or css and are offering c++ or java + TaggableModel.tagged_with(['rails, css'], :on => :needs, :any => true).tagged_with(['c++', 'java'], :on => :offerings, :any => true).to_a.should == [bob] + end + + it "should not return read-only records" do + TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + TaggableModel.tagged_with("ruby").first.should_not be_readonly + end + + it "should be able to get scoped tag counts" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + + TaggableModel.tagged_with("ruby").tag_counts(:order => 'tags.id').first.count.should == 2 # ruby + TaggableModel.tagged_with("ruby").skill_counts.first.count.should == 1 # ruby + end + + it "should be able to get all scoped tag counts" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + + TaggableModel.tagged_with("ruby").all_tag_counts(:order => 'tags.id').first.count.should == 3 # ruby + end + + it "should be able to get all scoped tags" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby") + + TaggableModel.tagged_with("ruby").all_tags(:order => 'tags.id').first.name.should == "ruby" + end + + it 'should only return tag counts for the available scope' do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby, java") + + TaggableModel.tagged_with('rails').all_tag_counts.should have(3).items + TaggableModel.tagged_with('rails').all_tag_counts.any? { |tag| tag.name == 'java' }.should be_false + + # Test specific join syntaxes: + frank.untaggable_models.create! + TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tag_counts.should have(2).items + TaggableModel.tagged_with('rails').joins(:untaggable_models => :taggable_model).all_tag_counts.should have(2).items + TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tag_counts.should have(2).items + end + + it 'should only return tags for the available scope' do + bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails") + charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby, java") + + TaggableModel.tagged_with('rails').all_tags.should have(3).items + TaggableModel.tagged_with('rails').all_tags.any? { |tag| tag.name == 'java' }.should be_false + + # Test specific join syntaxes: + frank.untaggable_models.create! + TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tags.should have(2).items + TaggableModel.tagged_with('rails').joins({ :untaggable_models => :taggable_model }).all_tags.should have(2).items + TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tags.should have(2).items + end + + it "should be able to set a custom tag context list" do + bob = TaggableModel.create(:name => "Bob") + bob.set_tag_list_on(:rotors, "spinning, jumping") + bob.tag_list_on(:rotors).should == ["spinning","jumping"] + bob.save + bob.reload + bob.tags_on(:rotors).should_not be_empty + end + + it "should be able to find tagged" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css") + steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby') + + TaggableModel.tagged_with("ruby", :order => 'taggable_models.name').to_a.should == [bob, frank, steve] + TaggableModel.tagged_with("ruby, rails", :order => 'taggable_models.name').to_a.should == [bob, frank] + TaggableModel.tagged_with(["ruby", "rails"], :order => 'taggable_models.name').to_a.should == [bob, frank] + end + + it "should be able to find tagged with quotation marks" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive, 'I love the ,comma,'") + TaggableModel.tagged_with("'I love the ,comma,'").should include(bob) + end + + it "should be able to find tagged with invalid tags" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive") + TaggableModel.tagged_with("sad, happier").should_not include(bob) + end + + it "should be able to find tagged with any tag" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css") + steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby') + + TaggableModel.tagged_with(["ruby", "java"], :order => 'taggable_models.name', :any => true).to_a.should == [bob, frank, steve] + TaggableModel.tagged_with(["c++", "fitter"], :order => 'taggable_models.name', :any => true).to_a.should == [bob, steve] + TaggableModel.tagged_with(["depressed", "css"], :order => 'taggable_models.name', :any => true).to_a.should == [bob, frank] + end + + context "wild: true" do + it "should use params as wildcards" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "bob, tricia") + frank = TaggableModel.create(:name => "Frank", :tag_list => "bobby, jim") + steve = TaggableModel.create(:name => "Steve", :tag_list => "john, patricia") + jim = TaggableModel.create(:name => "Jim", :tag_list => "jim, steve") + + + TaggableModel.tagged_with(["bob", "tricia"], :wild => true, :any => true).to_a.sort_by{|o| o.id}.should == [bob, frank, steve] + TaggableModel.tagged_with(["bob", "tricia"], :wild => true, :exclude => true).to_a.should == [jim] + end + end + + it "should be able to find tagged on a custom tag context" do + bob = TaggableModel.create(:name => "Bob") + bob.set_tag_list_on(:rotors, "spinning, jumping") + bob.tag_list_on(:rotors).should == ["spinning","jumping"] + bob.save + + TaggableModel.tagged_with("spinning", :on => :rotors).to_a.should == [bob] + end + + it "should be able to use named scopes to chain tag finds" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css") + frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css") + steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, python') + + # Let's only find those productive Rails developers + TaggableModel.tagged_with('rails', :on => :skills, :order => 'taggable_models.name').to_a.should == [bob, frank] + TaggableModel.tagged_with('happier', :on => :tags, :order => 'taggable_models.name').to_a.should == [bob, steve] + TaggableModel.tagged_with('rails', :on => :skills).tagged_with('happier', :on => :tags).to_a.should == [bob] + TaggableModel.tagged_with('rails').tagged_with('happier', :on => :tags).to_a.should == [bob] + end + + it "should be able to find tagged with only the matching tags" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "lazy, happier") + frank = TaggableModel.create(:name => "Frank", :tag_list => "fitter, happier, inefficient") + steve = TaggableModel.create(:name => 'Steve', :tag_list => "fitter, happier") + + TaggableModel.tagged_with("fitter, happier", :match_all => true).to_a.should == [steve] + end + + it "should be able to find tagged with some excluded tags" do + bob = TaggableModel.create(:name => "Bob", :tag_list => "happier, lazy") + frank = TaggableModel.create(:name => "Frank", :tag_list => "happier") + steve = TaggableModel.create(:name => 'Steve', :tag_list => "happier") + + TaggableModel.tagged_with("lazy", :exclude => true).to_a.should == [frank, steve] + end + + it "should return an empty scope for empty tags" do + TaggableModel.tagged_with('').should == [] + TaggableModel.tagged_with(' ').should == [] + TaggableModel.tagged_with(nil).should == [] + TaggableModel.tagged_with([]).should == [] + end + + it "should not create duplicate taggings" do + bob = TaggableModel.create(:name => "Bob") + lambda { + bob.tag_list << "happier" + bob.tag_list << "happier" + bob.save + }.should change(ActsAsTaggableOn::Tagging, :count).by(1) + end + + describe "Associations" do + before(:each) do + @taggable = TaggableModel.create(:tag_list => "awesome, epic") + end + + it "should not remove tags when creating associated objects" do + @taggable.untaggable_models.create! + @taggable.reload + @taggable.tag_list.should have(2).items + end + end + + describe "grouped_column_names_for method" do + it "should return all column names joined for Tag GROUP clause" do + @taggable.grouped_column_names_for(ActsAsTaggableOn::Tag).should == "tags.id, tags.name" + end + + it "should return all column names joined for TaggableModel GROUP clause" do + @taggable.grouped_column_names_for(TaggableModel).should == "taggable_models.id, taggable_models.name, taggable_models.type" + end + + it "should return all column names joined for NonStandardIdTaggableModel GROUP clause" do + @taggable.grouped_column_names_for(TaggableModel).should == "taggable_models.#{TaggableModel.primary_key}, taggable_models.name, taggable_models.type" + end + end + + describe "NonStandardIdTaggable" do + before(:each) do + clean_database! + @taggable = NonStandardIdTaggableModel.new(:name => "Bob Jones") + @taggables = [@taggable, NonStandardIdTaggableModel.new(:name => "John Doe")] + end + + it "should have tag types" do + [:tags, :languages, :skills, :needs, :offerings].each do |type| + NonStandardIdTaggableModel.tag_types.should include type + end + + @taggable.tag_types.should == NonStandardIdTaggableModel.tag_types + end + + it "should have tag_counts_on" do + NonStandardIdTaggableModel.tag_counts_on(:tags).should be_empty + + @taggable.tag_list = ["awesome", "epic"] + @taggable.save + + NonStandardIdTaggableModel.tag_counts_on(:tags).length.should == 2 + @taggable.tag_counts_on(:tags).length.should == 2 + end + + it "should have tags_on" do + NonStandardIdTaggableModel.tags_on(:tags).should be_empty + + @taggable.tag_list = ["awesome", "epic"] + @taggable.save + + NonStandardIdTaggableModel.tags_on(:tags).length.should == 2 + @taggable.tags_on(:tags).length.should == 2 + end + + it "should be able to create tags" do + @taggable.skill_list = "ruby, rails, css" + @taggable.instance_variable_get("@skill_list").instance_of?(ActsAsTaggableOn::TagList).should be_true + + lambda { + @taggable.save + }.should change(ActsAsTaggableOn::Tag, :count).by(3) + + @taggable.reload + @taggable.skill_list.sort.should == %w(ruby rails css).sort + end + + it "should be able to create tags through the tag list directly" do + @taggable.tag_list_on(:test).add("hello") + @taggable.tag_list_cache_on(:test).should_not be_empty + @taggable.tag_list_on(:test).should == ["hello"] + + @taggable.save + @taggable.save_tags + + @taggable.reload + @taggable.tag_list_on(:test).should == ["hello"] + end + end + + describe "Dirty Objects" do + context "with un-contexted tags" do + before(:each) do + @taggable = TaggableModel.create(:tag_list => "awesome, epic") + end + + context "when tag_list changed" do + before(:each) do + @taggable.changes.should == {} + @taggable.tag_list = 'one' + end + + it 'should show changes of dirty object' do + @taggable.changes.should == {"tag_list"=>["awesome, epic", ["one"]]} + end + + it 'flags tag_list as changed' do + @taggable.tag_list_changed?.should be_true + end + + it 'preserves original value' do + @taggable.tag_list_was.should == "awesome, epic" + end + + it 'shows what the change was' do + @taggable.tag_list_change.should == ["awesome, epic", ["one"]] + end + end + + context 'when tag_list is the same' do + before(:each) do + @taggable.tag_list = "awesome, epic" + end + + it 'is not flagged as changed' do + @taggable.tag_list_changed?.should be_false + end + + it 'does not show any changes to the taggable item' do + @taggable.changes.should == {} + end + end + end + + context "with context tags" do + before(:each) do + @taggable = TaggableModel.create(:language_list => "awesome, epic") + end + + context "when language_list changed" do + before(:each) do + @taggable.changes.should == {} + @taggable.language_list = 'one' + end + + it 'should show changes of dirty object' do + @taggable.changes.should == {"language_list"=>["awesome, epic", ["one"]]} + end + + it 'flags language_list as changed' do + @taggable.language_list_changed?.should be_true + end + + it 'preserves original value' do + @taggable.language_list_was.should == "awesome, epic" + end + + it 'shows what the change was' do + @taggable.language_list_change.should == ["awesome, epic", ["one"]] + end + + it 'shows what the changes were' do + @taggable.language_list_changes.should == ["awesome, epic", ["one"]] + end + end + + context 'when language_list is the same' do + before(:each) do + @taggable.language_list = "awesome, epic" + end + + it 'is not flagged as changed' do + @taggable.language_list_changed?.should be_false + end + + it 'does not show any changes to the taggable item' do + @taggable.changes.should == {} + end + end + end + end + + describe "Autogenerated methods" do + it "should be overridable" do + TaggableModel.create(:tag_list=>'woo').tag_list_submethod_called.should be_true + end + end +end + + diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagger_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagger_spec.rb new file mode 100644 index 000000000..ab0b2b91b --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagger_spec.rb @@ -0,0 +1,137 @@ +require 'spec_helper' + +describe "Tagger" do + before(:each) do + clean_database! + @user = User.create + @taggable = TaggableModel.create(:name => "Bob Jones") + end + + it "should have taggings" do + @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags) + @user.owned_taggings.size == 2 + end + + it "should have tags" do + @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags) + @user.owned_tags.size == 2 + end + + it "should scope objects returned by tagged_with by owners" do + @taggable2 = TaggableModel.create(:name => "Jim Jones") + @taggable3 = TaggableModel.create(:name => "Jane Doe") + + @user2 = User.new + @user.tag(@taggable, :with => 'ruby, scheme', :on => :tags) + @user2.tag(@taggable2, :with => 'ruby, scheme', :on => :tags) + @user2.tag(@taggable3, :with => 'ruby, scheme', :on => :tags) + + TaggableModel.tagged_with(%w(ruby scheme), :owned_by => @user).count.should == 1 + TaggableModel.tagged_with(%w(ruby scheme), :owned_by => @user2).count.should == 2 + end + + it "only returns objects tagged by owned_by when any is true" do + @user2 = User.new + @taggable2 = TaggableModel.create(:name => "Jim Jones") + @taggable3 = TaggableModel.create(:name => "Jane Doe") + + @user.tag(@taggable, :with => 'ruby', :on => :tags) + @user.tag(@taggable2, :with => 'java', :on => :tags) + @user2.tag(@taggable3, :with => 'ruby', :on => :tags) + + tags = TaggableModel.tagged_with(%w(ruby java), :owned_by => @user, :any => true) + tags.should match_array [@taggable, @taggable2] + end + + it "only returns objects tagged by owned_by when exclude is true" do + @user2 = User.new + @taggable2 = TaggableModel.create(:name => "Jim Jones") + @taggable3 = TaggableModel.create(:name => "Jane Doe") + + @user.tag(@taggable, :with => 'ruby', :on => :tags) + @user.tag(@taggable2, :with => 'java', :on => :tags) + @user2.tag(@taggable3, :with => 'java', :on => :tags) + + tags = TaggableModel.tagged_with(%w(ruby), :owned_by => @user, :exclude => true) + tags.should match_array [@taggable2] + end + + it "should not overlap tags from different taggers" do + @user2 = User.new + lambda{ + @user.tag(@taggable, :with => 'ruby, scheme', :on => :tags) + @user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags) + }.should change(ActsAsTaggableOn::Tagging, :count).by(6) + + [@user, @user2, @taggable].each(&:reload) + + @user.owned_tags.map(&:name).sort.should == %w(ruby scheme).sort + @user2.owned_tags.map(&:name).sort.should == %w(java python lisp ruby).sort + + @taggable.tags_from(@user).sort.should == %w(ruby scheme).sort + @taggable.tags_from(@user2).sort.should == %w(java lisp python ruby).sort + + @taggable.all_tags_list.sort.should == %w(ruby scheme java python lisp).sort + @taggable.all_tags_on(:tags).size.should == 5 + end + + it "should not lose tags from different taggers" do + @user2 = User.create + @user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags) + @user.tag(@taggable, :with => 'ruby, scheme', :on => :tags) + + lambda { + @user2.tag(@taggable, :with => 'java, python, lisp', :on => :tags) + }.should change(ActsAsTaggableOn::Tagging, :count).by(-1) + + [@user, @user2, @taggable].each(&:reload) + + @taggable.tags_from(@user).sort.should == %w(ruby scheme).sort + @taggable.tags_from(@user2).sort.should == %w(java python lisp).sort + + @taggable.all_tags_list.sort.should == %w(ruby scheme java python lisp).sort + @taggable.all_tags_on(:tags).length.should == 5 + end + + it "should not lose tags" do + @user2 = User.create + + @user.tag(@taggable, :with => 'awesome', :on => :tags) + @user2.tag(@taggable, :with => 'awesome, epic', :on => :tags) + + lambda { + @user2.tag(@taggable, :with => 'epic', :on => :tags) + }.should change(ActsAsTaggableOn::Tagging, :count).by(-1) + + @taggable.reload + @taggable.all_tags_list.should include('awesome') + @taggable.all_tags_list.should include('epic') + end + + it "should not lose tags" do + @taggable.update_attributes(:tag_list => 'ruby') + @user.tag(@taggable, :with => 'ruby, scheme', :on => :tags) + + [@taggable, @user].each(&:reload) + @taggable.tag_list.should == %w(ruby) + @taggable.all_tags_list.sort.should == %w(ruby scheme).sort + + lambda { + @taggable.update_attributes(:tag_list => "") + }.should change(ActsAsTaggableOn::Tagging, :count).by(-1) + + @taggable.tag_list.should == [] + @taggable.all_tags_list.sort.should == %w(ruby scheme).sort + end + + it "is tagger" do + @user.is_tagger?.should(be_true) + end + + it "should skip save if skip_save is passed as option" do + lambda { + @user.tag(@taggable, :with => 'epic', :on => :tags, :skip_save => true) + }.should_not change(ActsAsTaggableOn::Tagging, :count) + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagging_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagging_spec.rb new file mode 100644 index 000000000..7b5649260 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tagging_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe ActsAsTaggableOn::Tagging do + before(:each) do + clean_database! + @tagging = ActsAsTaggableOn::Tagging.new + end + + it "should not be valid with a invalid tag" do + @tagging.taggable = TaggableModel.create(:name => "Bob Jones") + @tagging.tag = ActsAsTaggableOn::Tag.new(:name => "") + @tagging.context = "tags" + + @tagging.should_not be_valid + + @tagging.errors[:tag_id].should == ["can't be blank"] + end + + it "should not create duplicate taggings" do + @taggable = TaggableModel.create(:name => "Bob Jones") + @tag = ActsAsTaggableOn::Tag.create(:name => "awesome") + + lambda { + 2.times { ActsAsTaggableOn::Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags') } + }.should change(ActsAsTaggableOn::Tagging, :count).by(1) + end + +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tags_helper_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tags_helper_spec.rb new file mode 100644 index 000000000..089f89390 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/tags_helper_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe ActsAsTaggableOn::TagsHelper do + before(:each) do + clean_database! + + @bob = TaggableModel.create(:name => "Bob Jones", :language_list => "ruby, php") + @tom = TaggableModel.create(:name => "Tom Marley", :language_list => "ruby, java") + @eve = TaggableModel.create(:name => "Eve Nodd", :language_list => "ruby, c++") + + @helper = class Helper + include ActsAsTaggableOn::TagsHelper + end.new + end + + it "should yield the proper css classes" do + tags = { } + + @helper.tag_cloud(TaggableModel.tag_counts_on(:languages), ["sucky", "awesome"]) do |tag, css_class| + tags[tag.name] = css_class + end + + tags["ruby"].should == "awesome" + tags["java"].should == "sucky" + tags["c++"].should == "sucky" + tags["php"].should == "sucky" + end + + it "should handle tags with zero counts (build for empty)" do + bob = ActsAsTaggableOn::Tag.create(:name => "php") + tom = ActsAsTaggableOn::Tag.create(:name => "java") + eve = ActsAsTaggableOn::Tag.create(:name => "c++") + + tags = { } + + @helper.tag_cloud(ActsAsTaggableOn::Tag.all, ["sucky", "awesome"]) do |tag, css_class| + tags[tag.name] = css_class + end + + tags["java"].should == "sucky" + tags["c++"].should == "sucky" + tags["php"].should == "sucky" + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/utils_spec.rb b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/utils_spec.rb new file mode 100644 index 000000000..75af44419 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/acts_as_taggable_on/utils_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe ActsAsTaggableOn::Utils do + describe "like_operator" do + before(:each) do + clean_database! + TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings) + @taggable = TaggableModel.new(:name => "Bob Jones") + end + + it "should return 'ILIKE' when the adapter is PostgreSQL" do + TaggableModel.connection.stub(:adapter_name).and_return("PostgreSQL") + TaggableModel.send(:like_operator).should == "ILIKE" + end + + it "should return 'LIKE' when the adapter is not PostgreSQL" do + TaggableModel.connection.stub(:adapter_name).and_return("MySQL") + TaggableModel.send(:like_operator).should == "LIKE" + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/bm.rb b/lib/plugins/acts-as-taggable-on/spec/bm.rb new file mode 100644 index 000000000..949dd475f --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/bm.rb @@ -0,0 +1,52 @@ +require 'active_record' +require 'action_view' +require File.expand_path('../../lib/acts-as-taggable-on', __FILE__) + +if defined?(ActiveRecord::Acts::TaggableOn) + ActiveRecord::Base.send :include, ActiveRecord::Acts::TaggableOn + ActiveRecord::Base.send :include, ActiveRecord::Acts::Tagger + ActionView::Base.send :include, TagsHelper if defined?(ActionView::Base) +end + +TEST_DATABASE_FILE = File.join(File.dirname(__FILE__), '..', 'test.sqlite3') +File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE) +ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => TEST_DATABASE_FILE + +ActiveRecord::Base.silence do + ActiveRecord::Migration.verbose = false + ActiveRecord::Schema.define :version => 0 do + create_table "taggings", :force => true do |t| + t.integer "tag_id", :limit => 11 + t.integer "taggable_id", :limit => 11 + t.string "taggable_type" + t.string "context" + t.datetime "created_at" + t.integer "tagger_id", :limit => 11 + t.string "tagger_type" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table :taggable_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + t.column :cached_tag_list, :string + end + end + + class TaggableModel < ActiveRecord::Base + acts_as_taggable + acts_as_taggable_on :languages + acts_as_taggable_on :skills + acts_as_taggable_on :needs, :offerings + end +end + +puts Benchmark.measure { + 1000.times { TaggableModel.create :tag_list => "awesome, epic, neat" } +} \ No newline at end of file diff --git a/lib/plugins/acts-as-taggable-on/spec/database.yml.sample b/lib/plugins/acts-as-taggable-on/spec/database.yml.sample new file mode 100644 index 000000000..97652ed57 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/database.yml.sample @@ -0,0 +1,19 @@ +sqlite3: + adapter: sqlite3 + database: acts_as_taggable_on.sqlite3 + +mysql: + adapter: mysql2 + hostname: localhost + username: root + password: + database: acts_as_taggable_on + charset: utf8 + +postgresql: + adapter: postgresql + hostname: localhost + username: postgres + password: + database: acts_as_taggable_on + encoding: utf8 diff --git a/lib/plugins/acts-as-taggable-on/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb b/lib/plugins/acts-as-taggable-on/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb new file mode 100644 index 000000000..32f012c3c --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +# Generators are not automatically loaded by Rails +require 'generators/acts_as_taggable_on/migration/migration_generator' + +describe ActsAsTaggableOn::MigrationGenerator do + # Tell the generator where to put its output (what it thinks of as Rails.root) + destination File.expand_path("../../../../../tmp", __FILE__) + + before do + prepare_destination + Rails::Generators.options[:rails][:orm] = :active_record + end + describe 'no arguments' do + before { run_generator } + + describe 'db/migrate/acts_as_taggable_on_migration.rb' do + subject { file('db/migrate/acts_as_taggable_on_migration.rb') } + it { should be_a_migration } + end + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/models.rb b/lib/plugins/acts-as-taggable-on/spec/models.rb new file mode 100644 index 000000000..133d4765c --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/models.rb @@ -0,0 +1,58 @@ +class TaggableModel < ActiveRecord::Base + acts_as_taggable + acts_as_taggable_on :languages + acts_as_taggable_on :skills + acts_as_taggable_on :needs, :offerings + has_many :untaggable_models + + attr_reader :tag_list_submethod_called + def tag_list=v + @tag_list_submethod_called = true + super + end +end + +class CachedModel < ActiveRecord::Base + acts_as_taggable +end + +class OtherCachedModel < ActiveRecord::Base + acts_as_taggable_on :languages, :statuses, :glasses +end + +class OtherTaggableModel < ActiveRecord::Base + acts_as_taggable_on :tags, :languages + acts_as_taggable_on :needs, :offerings +end + +class InheritingTaggableModel < TaggableModel +end + +class AlteredInheritingTaggableModel < TaggableModel + acts_as_taggable_on :parts +end + +class User < ActiveRecord::Base + acts_as_tagger +end + +class Student < User +end + +class UntaggableModel < ActiveRecord::Base + belongs_to :taggable_model +end + +class NonStandardIdTaggableModel < ActiveRecord::Base + primary_key = "an_id" + acts_as_taggable + acts_as_taggable_on :languages + acts_as_taggable_on :skills + acts_as_taggable_on :needs, :offerings + has_many :untaggable_models +end + +class OrderedTaggableModel < ActiveRecord::Base + acts_as_ordered_taggable + acts_as_ordered_taggable_on :colours +end diff --git a/lib/plugins/acts-as-taggable-on/spec/schema.rb b/lib/plugins/acts-as-taggable-on/spec/schema.rb new file mode 100644 index 000000000..4949f0107 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/schema.rb @@ -0,0 +1,61 @@ +ActiveRecord::Schema.define :version => 0 do + create_table "taggings", :force => true do |t| + t.integer "tag_id", :limit => 11 + t.integer "taggable_id", :limit => 11 + t.string "taggable_type" + t.string "context" + t.datetime "created_at" + t.integer "tagger_id", :limit => 11 + t.string "tagger_type" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table :taggable_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + end + + create_table :non_standard_id_taggable_models, :primary_key => "an_id", :force => true do |t| + t.column :name, :string + t.column :type, :string + end + + create_table :untaggable_models, :force => true do |t| + t.column :taggable_model_id, :integer + t.column :name, :string + end + + create_table :cached_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + t.column :cached_tag_list, :string + end + + create_table :other_cached_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + t.column :cached_language_list, :string + t.column :cached_status_list, :string + t.column :cached_glass_list, :string + end + + create_table :users, :force => true do |t| + t.column :name, :string + end + + create_table :other_taggable_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + end + + create_table :ordered_taggable_models, :force => true do |t| + t.column :name, :string + t.column :type, :string + end +end diff --git a/lib/plugins/acts-as-taggable-on/spec/spec_helper.rb b/lib/plugins/acts-as-taggable-on/spec/spec_helper.rb new file mode 100644 index 000000000..e317bc319 --- /dev/null +++ b/lib/plugins/acts-as-taggable-on/spec/spec_helper.rb @@ -0,0 +1,86 @@ +$LOAD_PATH << "." unless $LOAD_PATH.include?(".") +require 'logger' + +begin + require "rubygems" + require "bundler" + + if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.5") + raise RuntimeError, "Your bundler version is too old." + + "Run `gem install bundler` to upgrade." + end + + # Set up load paths for all bundled gems + Bundler.setup +rescue Bundler::GemNotFound + raise RuntimeError, "Bundler couldn't find some gems." + + "Did you run \`bundlee install\`?" +end + +Bundler.require +require File.expand_path('../../lib/acts-as-taggable-on', __FILE__) +require 'ammeter/init' + +unless [].respond_to?(:freq) + class Array + def freq + k=Hash.new(0) + each {|e| k[e]+=1} + k + end + end +end + +# set adapter to use, default is sqlite3 +# to use an alternative adapter run => rake spec DB='postgresql' +db_name = ENV['DB'] || 'sqlite3' +database_yml = File.expand_path('../database.yml', __FILE__) + +if File.exists?(database_yml) + active_record_configuration = YAML.load_file(database_yml) + + ActiveRecord::Base.configurations = active_record_configuration + config = ActiveRecord::Base.configurations[db_name] + + begin + ActiveRecord::Base.establish_connection(db_name) + ActiveRecord::Base.connection + rescue + case db_name + when /mysql/ + ActiveRecord::Base.establish_connection(config.merge('database' => nil)) + ActiveRecord::Base.connection.create_database(config['database'], {:charset => 'utf8', :collation => 'utf8_unicode_ci'}) + when 'postgresql' + ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) + ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => 'utf8')) + end + + ActiveRecord::Base.establish_connection(config) + end + + logger = ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log")) + ActiveRecord::Base.default_timezone = :utc + + begin + old_logger_level, logger.level = logger.level, ::Logger::ERROR + ActiveRecord::Migration.verbose = false + + load(File.dirname(__FILE__) + '/schema.rb') + load(File.dirname(__FILE__) + '/models.rb') + ensure + logger.level = old_logger_level + end + +else + raise "Please create #{database_yml} first to configure your database. Take a look at: #{database_yml}.sample" +end + +def clean_database! + models = [ActsAsTaggableOn::Tag, ActsAsTaggableOn::Tagging, TaggableModel, OtherTaggableModel, InheritingTaggableModel, + AlteredInheritingTaggableModel, User, UntaggableModel, OrderedTaggableModel] + models.each do |model| + ActiveRecord::Base.connection.execute "DELETE FROM #{model.table_name}" + end +end + +clean_database! diff --git a/lib/plugins/acts_as_activity_provider/init.rb b/lib/plugins/acts_as_activity_provider/init.rb new file mode 100644 index 000000000..5bf05da2c --- /dev/null +++ b/lib/plugins/acts_as_activity_provider/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_activity_provider' +ActiveRecord::Base.send(:include, Redmine::Acts::ActivityProvider) diff --git 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 new file mode 100644 index 000000000..f92aae250 --- /dev/null +++ b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb @@ -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 --git a/lib/plugins/acts_as_attachable/init.rb b/lib/plugins/acts_as_attachable/init.rb new file mode 100644 index 000000000..213e1d4b1 --- /dev/null +++ b/lib/plugins/acts_as_attachable/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_attachable' +ActiveRecord::Base.send(:include, Redmine::Acts::Attachable) diff --git a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb new file mode 100644 index 000000000..ca556919a --- /dev/null +++ b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.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. + +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 --git a/lib/plugins/acts_as_customizable/init.rb b/lib/plugins/acts_as_customizable/init.rb new file mode 100644 index 000000000..9036aa579 --- /dev/null +++ b/lib/plugins/acts_as_customizable/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_customizable' +ActiveRecord::Base.send(:include, Redmine::Acts::Customizable) diff --git a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb new file mode 100644 index 000000000..1f1aa1e44 --- /dev/null +++ b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb @@ -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 --git a/lib/plugins/acts_as_event/init.rb b/lib/plugins/acts_as_event/init.rb new file mode 100644 index 000000000..91051510a --- /dev/null +++ b/lib/plugins/acts_as_event/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_event' +ActiveRecord::Base.send(:include, Redmine::Acts::Event) diff --git a/lib/plugins/acts_as_event/lib/acts_as_event.rb b/lib/plugins/acts_as_event/lib/acts_as_event.rb new file mode 100644 index 000000000..e323c2b3e --- /dev/null +++ b/lib/plugins/acts_as_event/lib/acts_as_event.rb @@ -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 --git a/lib/plugins/acts_as_list/README b/lib/plugins/acts_as_list/README new file mode 100644 index 000000000..36ae3188e --- /dev/null +++ b/lib/plugins/acts_as_list/README @@ -0,0 +1,23 @@ +ActsAsList +========== + +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. + + +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 + + +Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license \ No newline at end of file diff --git a/lib/plugins/acts_as_list/init.rb b/lib/plugins/acts_as_list/init.rb new file mode 100644 index 000000000..eb87e8790 --- /dev/null +++ b/lib/plugins/acts_as_list/init.rb @@ -0,0 +1,3 @@ +$:.unshift "#{File.dirname(__FILE__)}/lib" +require 'active_record/acts/list' +ActiveRecord::Base.class_eval { include ActiveRecord::Acts::List } diff --git a/lib/plugins/acts_as_list/lib/active_record/acts/list.rb b/lib/plugins/acts_as_list/lib/active_record/acts/list.rb new file mode 100644 index 000000000..9361a768c --- /dev/null +++ b/lib/plugins/acts_as_list/lib/active_record/acts/list.rb @@ -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 _id + # (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: acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0' + 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 acts_as_list specified. Each method works + # by assuming the object to be the item in the list, so chapter.move_lower would move that chapter + # lower in the list of all chapters. Likewise, chapter.first? 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 (position_column) 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 --git a/lib/plugins/acts_as_list/test/list_test.rb b/lib/plugins/acts_as_list/test/list_test.rb new file mode 100644 index 000000000..e89cb8e12 --- /dev/null +++ b/lib/plugins/acts_as_list/test/list_test.rb @@ -0,0 +1,332 @@ +require 'test/unit' + +require 'rubygems' +gem 'activerecord', '>= 1.15.4.7794' +require 'active_record' + +require "#{File.dirname(__FILE__)}/../init" + +ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:") + +def setup_db + ActiveRecord::Schema.define(:version => 1) do + create_table :mixins do |t| + t.column :pos, :integer + t.column :parent_id, :integer + t.column :created_at, :datetime + t.column :updated_at, :datetime + end + end +end + +def teardown_db + ActiveRecord::Base.connection.tables.each do |table| + ActiveRecord::Base.connection.drop_table(table) + end +end + +class Mixin < ActiveRecord::Base +end + +class ListMixin < Mixin + acts_as_list :column => "pos", :scope => :parent + + def self.table_name() "mixins" end +end + +class ListMixinSub1 < ListMixin +end + +class ListMixinSub2 < ListMixin +end + +class ListWithStringScopeMixin < ActiveRecord::Base + acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}' + + def self.table_name() "mixins" end +end + + +class ListTest < Test::Unit::TestCase + + def setup + setup_db + (1..4).each { |counter| ListMixin.create! :pos => counter, :parent_id => 5 } + end + + def teardown + teardown_db + end + + def test_reordering + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).move_lower + assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).move_higher + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(1).move_to_bottom + assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(1).move_to_top + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).move_to_bottom + assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(4).move_to_top + assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + end + + def test_move_to_bottom_with_next_to_last_item + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + ListMixin.find(3).move_to_bottom + assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + end + + def test_next_prev + assert_equal ListMixin.find(2), ListMixin.find(1).lower_item + assert_nil ListMixin.find(1).higher_item + assert_equal ListMixin.find(3), ListMixin.find(4).higher_item + assert_nil ListMixin.find(4).lower_item + end + + def test_injection + item = ListMixin.new(:parent_id => 1) + assert_equal "parent_id = 1", item.scope_condition + assert_equal "pos", item.position_column + end + + def test_insert + new = ListMixin.create(:parent_id => 20) + assert_equal 1, new.pos + assert new.first? + assert new.last? + + new = ListMixin.create(:parent_id => 20) + assert_equal 2, new.pos + assert !new.first? + assert new.last? + + new = ListMixin.create(:parent_id => 20) + assert_equal 3, new.pos + assert !new.first? + assert new.last? + + new = ListMixin.create(:parent_id => 0) + assert_equal 1, new.pos + assert new.first? + assert new.last? + end + + def test_insert_at + new = ListMixin.create(:parent_id => 20) + assert_equal 1, new.pos + + new = ListMixin.create(:parent_id => 20) + assert_equal 2, new.pos + + new = ListMixin.create(:parent_id => 20) + assert_equal 3, new.pos + + new4 = ListMixin.create(:parent_id => 20) + assert_equal 4, new4.pos + + new4.insert_at(3) + assert_equal 3, new4.pos + + new.reload + assert_equal 4, new.pos + + new.insert_at(2) + assert_equal 2, new.pos + + new4.reload + assert_equal 4, new4.pos + + new5 = ListMixin.create(:parent_id => 20) + assert_equal 5, new5.pos + + new5.insert_at(1) + assert_equal 1, new5.pos + + new4.reload + assert_equal 5, new4.pos + end + + def test_delete_middle + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).destroy + + assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(1).pos + assert_equal 2, ListMixin.find(3).pos + assert_equal 3, ListMixin.find(4).pos + + ListMixin.find(1).destroy + + assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(3).pos + assert_equal 2, ListMixin.find(4).pos + end + + def test_with_string_based_scope + new = ListWithStringScopeMixin.create(:parent_id => 500) + assert_equal 1, new.pos + assert new.first? + assert new.last? + end + + def test_nil_scope + new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create + new2.move_higher + assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') + end + + + def test_remove_from_list_should_then_fail_in_list? + assert_equal true, ListMixin.find(1).in_list? + ListMixin.find(1).remove_from_list + assert_equal false, ListMixin.find(1).in_list? + end + + def test_remove_from_list_should_set_position_to_nil + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).remove_from_list + + assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(1).pos + assert_equal nil, ListMixin.find(2).pos + assert_equal 2, ListMixin.find(3).pos + assert_equal 3, ListMixin.find(4).pos + end + + def test_remove_before_destroy_does_not_shift_lower_items_twice + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + ListMixin.find(2).remove_from_list + ListMixin.find(2).destroy + + assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(1).pos + assert_equal 2, ListMixin.find(3).pos + assert_equal 3, ListMixin.find(4).pos + end + +end + +class ListSubTest < Test::Unit::TestCase + + def setup + setup_db + (1..4).each { |i| ((i % 2 == 1) ? ListMixinSub1 : ListMixinSub2).create! :pos => i, :parent_id => 5000 } + end + + def teardown + teardown_db + end + + def test_reordering + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(2).move_lower + assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(2).move_higher + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(1).move_to_bottom + assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(1).move_to_top + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(2).move_to_bottom + assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(4).move_to_top + assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + end + + def test_move_to_bottom_with_next_to_last_item + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + ListMixin.find(3).move_to_bottom + assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + end + + def test_next_prev + assert_equal ListMixin.find(2), ListMixin.find(1).lower_item + assert_nil ListMixin.find(1).higher_item + assert_equal ListMixin.find(3), ListMixin.find(4).higher_item + assert_nil ListMixin.find(4).lower_item + end + + def test_injection + item = ListMixin.new("parent_id"=>1) + assert_equal "parent_id = 1", item.scope_condition + assert_equal "pos", item.position_column + end + + def test_insert_at + new = ListMixin.create("parent_id" => 20) + assert_equal 1, new.pos + + new = ListMixinSub1.create("parent_id" => 20) + assert_equal 2, new.pos + + new = ListMixinSub2.create("parent_id" => 20) + assert_equal 3, new.pos + + new4 = ListMixin.create("parent_id" => 20) + assert_equal 4, new4.pos + + new4.insert_at(3) + assert_equal 3, new4.pos + + new.reload + assert_equal 4, new.pos + + new.insert_at(2) + assert_equal 2, new.pos + + new4.reload + assert_equal 4, new4.pos + + new5 = ListMixinSub1.create("parent_id" => 20) + assert_equal 5, new5.pos + + new5.insert_at(1) + assert_equal 1, new5.pos + + new4.reload + assert_equal 5, new4.pos + end + + def test_delete_middle + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + ListMixin.find(2).destroy + + assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(1).pos + assert_equal 2, ListMixin.find(3).pos + assert_equal 3, ListMixin.find(4).pos + + ListMixin.find(1).destroy + + assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) + + assert_equal 1, ListMixin.find(3).pos + assert_equal 2, ListMixin.find(4).pos + end + +end diff --git a/lib/plugins/acts_as_searchable/init.rb b/lib/plugins/acts_as_searchable/init.rb new file mode 100644 index 000000000..063721756 --- /dev/null +++ b/lib/plugins/acts_as_searchable/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_searchable' +ActiveRecord::Base.send(:include, Redmine::Acts::Searchable) diff --git a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb new file mode 100644 index 000000000..5a1f36752 --- /dev/null +++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb @@ -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 --git a/lib/plugins/acts_as_tree/README b/lib/plugins/acts_as_tree/README new file mode 100644 index 000000000..a6cc6a904 --- /dev/null +++ b/lib/plugins/acts_as_tree/README @@ -0,0 +1,26 @@ +acts_as_tree +============ + +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 + +Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license \ No newline at end of file diff --git a/lib/plugins/acts_as_tree/Rakefile b/lib/plugins/acts_as_tree/Rakefile new file mode 100644 index 000000000..da091d9dd --- /dev/null +++ b/lib/plugins/acts_as_tree/Rakefile @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test acts_as_tree plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for acts_as_tree plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'acts_as_tree' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/lib/plugins/acts_as_tree/init.rb b/lib/plugins/acts_as_tree/init.rb new file mode 100644 index 000000000..0901ddb4a --- /dev/null +++ b/lib/plugins/acts_as_tree/init.rb @@ -0,0 +1 @@ +ActiveRecord::Base.send :include, ActiveRecord::Acts::Tree diff --git a/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb b/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb new file mode 100644 index 000000000..d069da972 --- /dev/null +++ b/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb @@ -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 acts_as_tree: + # * siblings - Returns all the children of the parent, excluding the current node ([subchild2] when called on subchild1) + # * self_and_siblings - Returns all the children of the parent, including the current node ([subchild1, subchild2] when called on subchild1) + # * ancestors - Returns all the ancestors of the current node ([child1, root] when called on subchild2) + # * root - Returns the root of the current node (root when called on subchild2) + module ClassMethods + # Configuration options are: + # + # * foreign_key - specifies the column name to use for tracking of the tree (default: +parent_id+) + # * order - makes it possible to sort the children according to this SQL snippet. + # * counter_cache - 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 --git a/lib/plugins/acts_as_tree/test/abstract_unit.rb b/lib/plugins/acts_as_tree/test/abstract_unit.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/acts_as_tree/test/acts_as_tree_test.rb b/lib/plugins/acts_as_tree/test/acts_as_tree_test.rb new file mode 100644 index 000000000..018c58e1f --- /dev/null +++ b/lib/plugins/acts_as_tree/test/acts_as_tree_test.rb @@ -0,0 +1,219 @@ +require 'test/unit' + +require 'rubygems' +require 'active_record' + +$:.unshift File.dirname(__FILE__) + '/../lib' +require File.dirname(__FILE__) + '/../init' + +class Test::Unit::TestCase + def assert_queries(num = 1) + $query_count = 0 + yield + ensure + assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed." + end + + def assert_no_queries(&block) + assert_queries(0, &block) + end +end + +ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:") + +# AR keeps printing annoying schema statements +$stdout = StringIO.new + +def setup_db + ActiveRecord::Base.logger + ActiveRecord::Schema.define(:version => 1) do + create_table :mixins do |t| + t.column :type, :string + t.column :parent_id, :integer + end + end +end + +def teardown_db + ActiveRecord::Base.connection.tables.each do |table| + ActiveRecord::Base.connection.drop_table(table) + end +end + +class Mixin < ActiveRecord::Base +end + +class TreeMixin < Mixin + acts_as_tree :foreign_key => "parent_id", :order => "id" +end + +class TreeMixinWithoutOrder < Mixin + acts_as_tree :foreign_key => "parent_id" +end + +class RecursivelyCascadedTreeMixin < Mixin + acts_as_tree :foreign_key => "parent_id" + has_one :first_child, :class_name => 'RecursivelyCascadedTreeMixin', :foreign_key => :parent_id +end + +class TreeTest < Test::Unit::TestCase + + def setup + setup_db + @root1 = TreeMixin.create! + @root_child1 = TreeMixin.create! :parent_id => @root1.id + @child1_child = TreeMixin.create! :parent_id => @root_child1.id + @root_child2 = TreeMixin.create! :parent_id => @root1.id + @root2 = TreeMixin.create! + @root3 = TreeMixin.create! + end + + def teardown + teardown_db + end + + def test_children + assert_equal @root1.children, [@root_child1, @root_child2] + assert_equal @root_child1.children, [@child1_child] + assert_equal @child1_child.children, [] + assert_equal @root_child2.children, [] + end + + def test_parent + assert_equal @root_child1.parent, @root1 + assert_equal @root_child1.parent, @root_child2.parent + assert_nil @root1.parent + end + + def test_delete + assert_equal 6, TreeMixin.count + @root1.destroy + assert_equal 2, TreeMixin.count + @root2.destroy + @root3.destroy + assert_equal 0, TreeMixin.count + end + + def test_insert + @extra = @root1.children.create + + assert @extra + + assert_equal @extra.parent, @root1 + + assert_equal 3, @root1.children.size + assert @root1.children.include?(@extra) + assert @root1.children.include?(@root_child1) + assert @root1.children.include?(@root_child2) + end + + def test_ancestors + assert_equal [], @root1.ancestors + assert_equal [@root1], @root_child1.ancestors + assert_equal [@root_child1, @root1], @child1_child.ancestors + assert_equal [@root1], @root_child2.ancestors + assert_equal [], @root2.ancestors + assert_equal [], @root3.ancestors + end + + def test_root + assert_equal @root1, TreeMixin.root + assert_equal @root1, @root1.root + assert_equal @root1, @root_child1.root + assert_equal @root1, @child1_child.root + assert_equal @root1, @root_child2.root + assert_equal @root2, @root2.root + assert_equal @root3, @root3.root + end + + def test_roots + assert_equal [@root1, @root2, @root3], TreeMixin.roots + end + + def test_siblings + assert_equal [@root2, @root3], @root1.siblings + assert_equal [@root_child2], @root_child1.siblings + assert_equal [], @child1_child.siblings + assert_equal [@root_child1], @root_child2.siblings + assert_equal [@root1, @root3], @root2.siblings + assert_equal [@root1, @root2], @root3.siblings + end + + def test_self_and_siblings + assert_equal [@root1, @root2, @root3], @root1.self_and_siblings + assert_equal [@root_child1, @root_child2], @root_child1.self_and_siblings + assert_equal [@child1_child], @child1_child.self_and_siblings + assert_equal [@root_child1, @root_child2], @root_child2.self_and_siblings + assert_equal [@root1, @root2, @root3], @root2.self_and_siblings + assert_equal [@root1, @root2, @root3], @root3.self_and_siblings + end +end + +class TreeTestWithEagerLoading < Test::Unit::TestCase + + def setup + teardown_db + setup_db + @root1 = TreeMixin.create! + @root_child1 = TreeMixin.create! :parent_id => @root1.id + @child1_child = TreeMixin.create! :parent_id => @root_child1.id + @root_child2 = TreeMixin.create! :parent_id => @root1.id + @root2 = TreeMixin.create! + @root3 = TreeMixin.create! + + @rc1 = RecursivelyCascadedTreeMixin.create! + @rc2 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc1.id + @rc3 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc2.id + @rc4 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc3.id + end + + def teardown + teardown_db + end + + def test_eager_association_loading + roots = TreeMixin.find(:all, :include => :children, :conditions => "mixins.parent_id IS NULL", :order => "mixins.id") + assert_equal [@root1, @root2, @root3], roots + assert_no_queries do + assert_equal 2, roots[0].children.size + assert_equal 0, roots[1].children.size + assert_equal 0, roots[2].children.size + end + end + + def test_eager_association_loading_with_recursive_cascading_three_levels_has_many + root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :children => { :children => :children } }, :order => 'mixins.id') + assert_equal @rc4, assert_no_queries { root_node.children.first.children.first.children.first } + end + + def test_eager_association_loading_with_recursive_cascading_three_levels_has_one + root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :first_child => { :first_child => :first_child } }, :order => 'mixins.id') + assert_equal @rc4, assert_no_queries { root_node.first_child.first_child.first_child } + end + + def test_eager_association_loading_with_recursive_cascading_three_levels_belongs_to + leaf_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :parent => { :parent => :parent } }, :order => 'mixins.id DESC') + assert_equal @rc1, assert_no_queries { leaf_node.parent.parent.parent } + end +end + +class TreeTestWithoutOrder < Test::Unit::TestCase + + def setup + setup_db + @root1 = TreeMixinWithoutOrder.create! + @root2 = TreeMixinWithoutOrder.create! + end + + def teardown + teardown_db + end + + def test_root + assert [@root1, @root2].include?(TreeMixinWithoutOrder.root) + end + + def test_roots + assert_equal [], [@root1, @root2] - TreeMixinWithoutOrder.roots + end +end diff --git a/lib/plugins/acts_as_tree/test/database.yml b/lib/plugins/acts_as_tree/test/database.yml new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/acts_as_tree/test/fixtures/mixin.rb b/lib/plugins/acts_as_tree/test/fixtures/mixin.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/acts_as_tree/test/fixtures/mixins.yml b/lib/plugins/acts_as_tree/test/fixtures/mixins.yml new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/acts_as_tree/test/schema.rb b/lib/plugins/acts_as_tree/test/schema.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/acts_as_versioned/CHANGELOG b/lib/plugins/acts_as_versioned/CHANGELOG new file mode 100644 index 000000000..a5d339cc7 --- /dev/null +++ b/lib/plugins/acts_as_versioned/CHANGELOG @@ -0,0 +1,74 @@ +*SVN* (version numbers are overrated) + +* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson] + +*0.5.1* + +* (8 Aug 2006) Versioned models now belong to the unversioned model. @article_version.article.class => Article [Aslak Hellesoy] + +*0.5* # do versions even matter for plugins? + +* (21 Apr 2006) Added without_locking and without_revision methods. + + Foo.without_revision do + @foo.update_attributes ... + end + +*0.4* + +* (28 March 2006) Rename non_versioned_fields to non_versioned_columns (old one is kept for compatibility). +* (28 March 2006) Made explicit documentation note that string column names are required for non_versioned_columns. + +*0.3.1* + +* (7 Jan 2006) explicitly set :foreign_key option for the versioned model's belongs_to assocation for STI [Caged] +* (7 Jan 2006) added tests to prove has_many :through joins work + +*0.3* + +* (2 Jan 2006) added ability to share a mixin with versioned class +* (2 Jan 2006) changed the dynamic version model to MyModel::Version + +*0.2.4* + +* (27 Nov 2005) added note about possible destructive behavior of if_changed? [Michael Schuerig] + +*0.2.3* + +* (12 Nov 2005) fixed bug with old behavior of #blank? [Michael Schuerig] +* (12 Nov 2005) updated tests to use ActiveRecord Schema + +*0.2.2* + +* (3 Nov 2005) added documentation note to #acts_as_versioned [Martin Jul] + +*0.2.1* + +* (6 Oct 2005) renamed dirty? to changed? to keep it uniform. it was aliased to keep it backwards compatible. + +*0.2* + +* (6 Oct 2005) added find_versions and find_version class methods. + +* (6 Oct 2005) removed transaction from create_versioned_table(). + this way you can specify your own transaction around a group of operations. + +* (30 Sep 2005) fixed bug where find_versions() would order by 'version' twice. (found by Joe Clark) + +* (26 Sep 2005) added :sequence_name option to acts_as_versioned to set the sequence name on the versioned model + +*0.1.3* (18 Sep 2005) + +* First RubyForge release + +*0.1.2* + +* check if module is already included when acts_as_versioned is called + +*0.1.1* + +* Adding tests and rdocs + +*0.1* + +* Initial transfer from Rails ticket: http://dev.rubyonrails.com/ticket/1974 \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/MIT-LICENSE b/lib/plugins/acts_as_versioned/MIT-LICENSE new file mode 100644 index 000000000..5851fdae1 --- /dev/null +++ b/lib/plugins/acts_as_versioned/MIT-LICENSE @@ -0,0 +1,20 @@ +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. \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/README b/lib/plugins/acts_as_versioned/README new file mode 100644 index 000000000..8961f0522 --- /dev/null +++ b/lib/plugins/acts_as_versioned/README @@ -0,0 +1,28 @@ += acts_as_versioned + +This library adds simple versioning to an ActiveRecord module. ActiveRecord is required. + +== Resources + +Install + +* gem install acts_as_versioned + +Rubyforge project + +* http://rubyforge.org/projects/ar-versioned + +RDocs + +* http://ar-versioned.rubyforge.org + +Subversion + +* http://techno-weenie.net/svn/projects/acts_as_versioned + +Collaboa + +* http://collaboa.techno-weenie.net/repository/browse/acts_as_versioned + +Special thanks to Dreamer on ##rubyonrails for help in early testing. His ServerSideWiki (http://serversidewiki.com) +was the first project to use acts_as_versioned in the wild. \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/RUNNING_UNIT_TESTS b/lib/plugins/acts_as_versioned/RUNNING_UNIT_TESTS new file mode 100644 index 000000000..a6e55b841 --- /dev/null +++ b/lib/plugins/acts_as_versioned/RUNNING_UNIT_TESTS @@ -0,0 +1,41 @@ +== Creating the test database + +The default name for the test databases is "activerecord_versioned". If you +want to use another database name then be sure to update the connection +adapter setups you want to test with in test/connections//connection.rb. +When you have the database online, you can import the fixture tables with +the test/fixtures/db_definitions/*.sql files. + +Make sure that you create database objects with the same user that you specified in i +connection.rb otherwise (on Postgres, at least) tests for default values will fail. + +== Running with Rake + +The easiest way to run the unit tests is through Rake. The default task runs +the entire test suite for all the adapters. You can also run the suite on just +one adapter by using the tasks test_mysql_ruby, test_ruby_mysql, test_sqlite, +or test_postresql. For more information, checkout the full array of rake tasks with "rake -T" + +Rake can be found at http://rake.rubyforge.org + +== Running by hand + +Unit tests are located in test directory. If you only want to run a single test suite, +or don't want to bother with Rake, you can do so with something like: + + cd test; ruby -I "connections/native_mysql" base_test.rb + +That'll run the base suite using the MySQL-Ruby adapter. Change the adapter +and test suite name as needed. + +== Faster tests + +If you are using a database that supports transactions, you can set the +"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures. +This gives a very large speed boost. With rake: + + rake AR_TX_FIXTURES=yes + +Or, by hand: + + AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb diff --git a/lib/plugins/acts_as_versioned/Rakefile b/lib/plugins/acts_as_versioned/Rakefile new file mode 100644 index 000000000..3ae69e961 --- /dev/null +++ b/lib/plugins/acts_as_versioned/Rakefile @@ -0,0 +1,182 @@ +require 'rubygems' + +Gem::manage_gems + +require 'rake/rdoctask' +require 'rake/packagetask' +require 'rake/gempackagetask' +require 'rake/testtask' +require 'rake/contrib/rubyforgepublisher' + +PKG_NAME = 'acts_as_versioned' +PKG_VERSION = '0.3.1' +PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" +PROD_HOST = "technoweenie@bidwell.textdrive.com" +RUBY_FORGE_PROJECT = 'ar-versioned' +RUBY_FORGE_USER = 'technoweenie' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the calculations plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the calculations plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "#{PKG_NAME} -- Simple versioning with active record models" + rdoc.options << '--line-numbers --inline-source' + rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS') + rdoc.rdoc_files.include('lib/**/*.rb') +end + +spec = Gem::Specification.new do |s| + s.name = PKG_NAME + s.version = PKG_VERSION + s.platform = Gem::Platform::RUBY + s.summary = "Simple versioning with active record models" + s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS) + s.files.delete "acts_as_versioned_plugin.sqlite.db" + s.files.delete "acts_as_versioned_plugin.sqlite3.db" + s.files.delete "test/debug.log" + s.require_path = 'lib' + s.autorequire = 'acts_as_versioned' + s.has_rdoc = true + s.test_files = Dir['test/**/*_test.rb'] + s.add_dependency 'activerecord', '>= 1.10.1' + s.add_dependency 'activesupport', '>= 1.1.1' + s.author = "Rick Olson" + s.email = "technoweenie@gmail.com" + s.homepage = "http://techno-weenie.net" +end + +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_tar = true +end + +desc "Publish the API documentation" +task :pdoc => [:rdoc] do + Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload +end + +desc 'Publish the gem and API docs' +task :publish => [:pdoc, :rubyforge_upload] + +desc "Publish the release files to RubyForge." +task :rubyforge_upload => :package do + files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } + + if RUBY_FORGE_PROJECT then + require 'net/http' + require 'open-uri' + + project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" + project_data = open(project_uri) { |data| data.read } + group_id = project_data[/[?&]group_id=(\d+)/, 1] + raise "Couldn't get group id" unless group_id + + # This echos password to shell which is a bit sucky + if ENV["RUBY_FORGE_PASSWORD"] + password = ENV["RUBY_FORGE_PASSWORD"] + else + print "#{RUBY_FORGE_USER}@rubyforge.org's password: " + password = STDIN.gets.chomp + end + + login_response = Net::HTTP.start("rubyforge.org", 80) do |http| + data = [ + "login=1", + "form_loginname=#{RUBY_FORGE_USER}", + "form_pw=#{password}" + ].join("&") + http.post("/account/login.php", data) + end + + cookie = login_response["set-cookie"] + raise "Login failed" unless cookie + headers = { "Cookie" => cookie } + + release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" + release_data = open(release_uri, headers) { |data| data.read } + package_id = release_data[/[?&]package_id=(\d+)/, 1] + raise "Couldn't get package id" unless package_id + + first_file = true + release_id = "" + + files.each do |filename| + basename = File.basename(filename) + file_ext = File.extname(filename) + file_data = File.open(filename, "rb") { |file| file.read } + + puts "Releasing #{basename}..." + + release_response = Net::HTTP.start("rubyforge.org", 80) do |http| + release_date = Time.now.strftime("%Y-%m-%d %H:%M") + type_map = { + ".zip" => "3000", + ".tgz" => "3110", + ".gz" => "3110", + ".gem" => "1400" + }; type_map.default = "9999" + type = type_map[file_ext] + boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" + + query_hash = if first_file then + { + "group_id" => group_id, + "package_id" => package_id, + "release_name" => PKG_FILE_NAME, + "release_date" => release_date, + "type_id" => type, + "processor_id" => "8000", # Any + "release_notes" => "", + "release_changes" => "", + "preformatted" => "1", + "submit" => "1" + } + else + { + "group_id" => group_id, + "release_id" => release_id, + "package_id" => package_id, + "step2" => "1", + "type_id" => type, + "processor_id" => "8000", # Any + "submit" => "Add This File" + } + end + + query = "?" + query_hash.map do |(name, value)| + [name, URI.encode(value)].join("=") + end.join("&") + + data = [ + "--" + boundary, + "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", + "Content-Type: application/octet-stream", + "Content-Transfer-Encoding: binary", + "", file_data, "" + ].join("\x0D\x0A") + + release_headers = headers.merge( + "Content-Type" => "multipart/form-data; boundary=#{boundary}" + ) + + target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" + http.post(target + query, data, release_headers) + end + + if first_file then + release_id = release_response.body[/release_id=(\d+)/, 1] + raise("Couldn't get release id") unless release_id + end + + first_file = false + end + end +end \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/init.rb b/lib/plugins/acts_as_versioned/init.rb new file mode 100644 index 000000000..5937bbc7c --- /dev/null +++ b/lib/plugins/acts_as_versioned/init.rb @@ -0,0 +1 @@ +require 'acts_as_versioned' \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb b/lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb new file mode 100644 index 000000000..b63c891e4 --- /dev/null +++ b/lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb @@ -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 + # + # * class_name - versioned model class name (default: PageVersion in the above example) + # * table_name - versioned model table name (default: page_versions in the above example) + # * foreign_key - foreign key used to relate the versioned model to the original model (default: page_id in the above example) + # * inheritance_column - name of the column to save the model's inheritance_column value for STI. (default: versioned_type) + # * version_column - name of the column in the model that keeps the version number (default: version) + # * sequence_name - name of the custom sequence to be used by the versioned model. + # * limit - number of revisions to keep, defaults to unlimited + # * if - 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 :if option + # !expired? + # end + # end + # + # * if_changed - 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 + # + # * extend - 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 acts_as_versioned. + # 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 version_condition_met? and changed?. + 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 find + 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 --git a/lib/plugins/acts_as_versioned/test/abstract_unit.rb b/lib/plugins/acts_as_versioned/test/abstract_unit.rb new file mode 100644 index 000000000..86f50620c --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/abstract_unit.rb @@ -0,0 +1,41 @@ +$:.unshift(File.dirname(__FILE__) + '/../../../rails/activesupport/lib') +$:.unshift(File.dirname(__FILE__) + '/../../../rails/activerecord/lib') +$:.unshift(File.dirname(__FILE__) + '/../lib') +require 'test/unit' +begin + require 'active_support' + require 'active_record' + require 'active_record/fixtures' +rescue LoadError + require 'rubygems' + retry +end +require 'acts_as_versioned' + +config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml')) +ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log") +ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']} +ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test']) + +load(File.dirname(__FILE__) + "/schema.rb") + +# set up custom sequence on widget_versions for DBs that support sequences +if ENV['DB'] == 'postgresql' + ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil + ActiveRecord::Base.connection.remove_column :widget_versions, :id + ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;" + ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');" +end + +Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/" +$:.unshift(Test::Unit::TestCase.fixture_path) + +class Test::Unit::TestCase #:nodoc: + # Turn off transactional fixtures if you're working with MyISAM tables in MySQL + self.use_transactional_fixtures = true + + # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david) + self.use_instantiated_fixtures = false + + # Add more helper methods to be used by all tests here... +end \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/database.yml b/lib/plugins/acts_as_versioned/test/database.yml new file mode 100644 index 000000000..506e6bd37 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/database.yml @@ -0,0 +1,18 @@ +sqlite: + :adapter: sqlite + :dbfile: acts_as_versioned_plugin.sqlite.db +sqlite3: + :adapter: sqlite3 + :dbfile: acts_as_versioned_plugin.sqlite3.db +postgresql: + :adapter: postgresql + :username: postgres + :password: postgres + :database: acts_as_versioned_plugin_test + :min_messages: ERROR +mysql: + :adapter: mysql + :host: localhost + :username: rails + :password: + :database: acts_as_versioned_plugin_test \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/fixtures/authors.yml b/lib/plugins/acts_as_versioned/test/fixtures/authors.yml new file mode 100644 index 000000000..bd7a5aed6 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/authors.yml @@ -0,0 +1,6 @@ +caged: + id: 1 + name: caged +mly: + id: 2 + name: mly \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/fixtures/landmark.rb b/lib/plugins/acts_as_versioned/test/fixtures/landmark.rb new file mode 100644 index 000000000..cb9b93057 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/landmark.rb @@ -0,0 +1,3 @@ +class Landmark < ActiveRecord::Base + acts_as_versioned :if_changed => [ :name, :longitude, :latitude ] +end diff --git a/lib/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml b/lib/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml new file mode 100644 index 000000000..2dbd54ed2 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml @@ -0,0 +1,7 @@ +washington: + id: 1 + landmark_id: 1 + version: 1 + name: Washington, D.C. + latitude: 38.895 + longitude: -77.036667 diff --git a/lib/plugins/acts_as_versioned/test/fixtures/landmarks.yml b/lib/plugins/acts_as_versioned/test/fixtures/landmarks.yml new file mode 100644 index 000000000..46d96176a --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/landmarks.yml @@ -0,0 +1,6 @@ +washington: + id: 1 + name: Washington, D.C. + latitude: 38.895 + longitude: -77.036667 + version: 1 diff --git a/lib/plugins/acts_as_versioned/test/fixtures/locked_pages.yml b/lib/plugins/acts_as_versioned/test/fixtures/locked_pages.yml new file mode 100644 index 000000000..318e776cb --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/locked_pages.yml @@ -0,0 +1,10 @@ +welcome: + id: 1 + title: Welcome to the weblog + lock_version: 24 + type: LockedPage +thinking: + id: 2 + title: So I was thinking + lock_version: 24 + type: SpecialLockedPage diff --git a/lib/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml b/lib/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml new file mode 100644 index 000000000..5c978e629 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml @@ -0,0 +1,27 @@ +welcome_1: + id: 1 + page_id: 1 + title: Welcome to the weblg + version: 23 + version_type: LockedPage + +welcome_2: + id: 2 + page_id: 1 + title: Welcome to the weblog + version: 24 + version_type: LockedPage + +thinking_1: + id: 3 + page_id: 2 + title: So I was thinking!!! + version: 23 + version_type: SpecialLockedPage + +thinking_2: + id: 4 + page_id: 2 + title: So I was thinking + version: 24 + version_type: SpecialLockedPage diff --git a/lib/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb b/lib/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb new file mode 100644 index 000000000..9512b5e82 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb @@ -0,0 +1,13 @@ +class AddVersionedTables < ActiveRecord::Migration + def self.up + create_table("things") do |t| + t.column :title, :text + end + Thing.create_versioned_table + end + + def self.down + Thing.drop_versioned_table + drop_table "things" rescue nil + end +end \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/fixtures/page.rb b/lib/plugins/acts_as_versioned/test/fixtures/page.rb new file mode 100644 index 000000000..f133e351a --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/page.rb @@ -0,0 +1,43 @@ +class Page < ActiveRecord::Base + belongs_to :author + has_many :authors, :through => :versions, :order => 'name' + belongs_to :revisor, :class_name => 'Author' + has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name' + acts_as_versioned :if => :feeling_good? do + def self.included(base) + base.cattr_accessor :feeling_good + base.feeling_good = true + base.belongs_to :author + base.belongs_to :revisor, :class_name => 'Author' + end + + def feeling_good? + @@feeling_good == true + end + end +end + +module LockedPageExtension + def hello_world + 'hello_world' + end +end + +class LockedPage < ActiveRecord::Base + acts_as_versioned \ + :inheritance_column => :version_type, + :foreign_key => :page_id, + :table_name => :locked_pages_revisions, + :class_name => 'LockedPageRevision', + :version_column => :lock_version, + :limit => 2, + :if_changed => :title, + :extend => LockedPageExtension +end + +class SpecialLockedPage < LockedPage +end + +class Author < ActiveRecord::Base + has_many :pages +end \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/fixtures/page_versions.yml b/lib/plugins/acts_as_versioned/test/fixtures/page_versions.yml new file mode 100644 index 000000000..ef565fa4f --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/page_versions.yml @@ -0,0 +1,16 @@ +welcome_2: + id: 1 + page_id: 1 + title: Welcome to the weblog + body: Such a lovely day + version: 24 + author_id: 1 + revisor_id: 1 +welcome_1: + id: 2 + page_id: 1 + title: Welcome to the weblg + body: Such a lovely day + version: 23 + author_id: 2 + revisor_id: 2 diff --git a/lib/plugins/acts_as_versioned/test/fixtures/pages.yml b/lib/plugins/acts_as_versioned/test/fixtures/pages.yml new file mode 100644 index 000000000..07ac51f97 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/pages.yml @@ -0,0 +1,7 @@ +welcome: + id: 1 + title: Welcome to the weblog + body: Such a lovely day + version: 24 + author_id: 1 + revisor_id: 1 \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/fixtures/widget.rb b/lib/plugins/acts_as_versioned/test/fixtures/widget.rb new file mode 100644 index 000000000..086ac2b40 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/fixtures/widget.rb @@ -0,0 +1,6 @@ +class Widget < ActiveRecord::Base + acts_as_versioned :sequence_name => 'widgets_seq', :association_options => { + :dependent => :nullify, :order => 'version desc' + } + non_versioned_columns << 'foo' +end \ No newline at end of file diff --git a/lib/plugins/acts_as_versioned/test/migration_test.rb b/lib/plugins/acts_as_versioned/test/migration_test.rb new file mode 100644 index 000000000..4ead4a8fe --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/migration_test.rb @@ -0,0 +1,46 @@ +require File.join(File.dirname(__FILE__), 'abstract_unit') + +if ActiveRecord::Base.connection.supports_migrations? + class Thing < ActiveRecord::Base + attr_accessor :version + acts_as_versioned + end + + class MigrationTest < Test::Unit::TestCase + self.use_transactional_fixtures = false + def teardown + if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information) + ActiveRecord::Base.connection.initialize_schema_information + ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0" + else + ActiveRecord::Base.connection.initialize_schema_migrations_table + ActiveRecord::Base.connection.assume_migrated_upto_version(0) + end + + Thing.connection.drop_table "things" rescue nil + Thing.connection.drop_table "thing_versions" rescue nil + Thing.reset_column_information + end + + def test_versioned_migration + assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' } + # take 'er up + ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/') + t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing' + assert_equal 1, t.versions.size + + # check that the price column has remembered its value correctly + assert_equal t.price, t.versions.first.price + assert_equal t.title, t.versions.first.title + assert_equal t[:type], t.versions.first[:type] + + # make sure that the precision of the price column has been preserved + assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision + assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale + + # now lets take 'er back down + ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/') + assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' } + end + end +end diff --git a/lib/plugins/acts_as_versioned/test/schema.rb b/lib/plugins/acts_as_versioned/test/schema.rb new file mode 100644 index 000000000..7d5153d07 --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/schema.rb @@ -0,0 +1,68 @@ +ActiveRecord::Schema.define(:version => 0) do + create_table :pages, :force => true do |t| + t.column :version, :integer + t.column :title, :string, :limit => 255 + t.column :body, :text + t.column :updated_on, :datetime + t.column :author_id, :integer + t.column :revisor_id, :integer + end + + create_table :page_versions, :force => true do |t| + t.column :page_id, :integer + t.column :version, :integer + t.column :title, :string, :limit => 255 + t.column :body, :text + t.column :updated_on, :datetime + t.column :author_id, :integer + t.column :revisor_id, :integer + end + + create_table :authors, :force => true do |t| + t.column :page_id, :integer + t.column :name, :string + end + + create_table :locked_pages, :force => true do |t| + t.column :lock_version, :integer + t.column :title, :string, :limit => 255 + t.column :type, :string, :limit => 255 + end + + create_table :locked_pages_revisions, :force => true do |t| + t.column :page_id, :integer + t.column :version, :integer + t.column :title, :string, :limit => 255 + t.column :version_type, :string, :limit => 255 + t.column :updated_at, :datetime + end + + create_table :widgets, :force => true do |t| + t.column :name, :string, :limit => 50 + t.column :foo, :string + t.column :version, :integer + t.column :updated_at, :datetime + end + + create_table :widget_versions, :force => true do |t| + t.column :widget_id, :integer + t.column :name, :string, :limit => 50 + t.column :version, :integer + t.column :updated_at, :datetime + end + + create_table :landmarks, :force => true do |t| + t.column :name, :string + t.column :latitude, :float + t.column :longitude, :float + t.column :version, :integer + end + + create_table :landmark_versions, :force => true do |t| + t.column :landmark_id, :integer + t.column :name, :string + t.column :latitude, :float + t.column :longitude, :float + t.column :version, :integer + end +end diff --git a/lib/plugins/acts_as_versioned/test/versioned_test.rb b/lib/plugins/acts_as_versioned/test/versioned_test.rb new file mode 100644 index 000000000..a7bc2082b --- /dev/null +++ b/lib/plugins/acts_as_versioned/test/versioned_test.rb @@ -0,0 +1,347 @@ +require File.join(File.dirname(__FILE__), 'abstract_unit') +require File.join(File.dirname(__FILE__), 'fixtures/page') +require File.join(File.dirname(__FILE__), 'fixtures/widget') + +class VersionedTest < Test::Unit::TestCase + fixtures :pages, :page_versions, :locked_pages, :locked_pages_revisions, :authors, :landmarks, :landmark_versions + set_fixture_class :page_versions => Page::Version + + def test_saves_versioned_copy + p = Page.create! :title => 'first title', :body => 'first body' + assert !p.new_record? + assert_equal 1, p.versions.size + assert_equal 1, p.version + assert_instance_of Page.versioned_class, p.versions.first + end + + def test_saves_without_revision + p = pages(:welcome) + old_versions = p.versions.count + + p.save_without_revision + + p.without_revision do + p.update_attributes :title => 'changed' + end + + assert_equal old_versions, p.versions.count + end + + def test_rollback_with_version_number + p = pages(:welcome) + assert_equal 24, p.version + assert_equal 'Welcome to the weblog', p.title + + assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23" + assert_equal 23, p.version + assert_equal 'Welcome to the weblg', p.title + end + + def test_versioned_class_name + assert_equal 'Version', Page.versioned_class_name + assert_equal 'LockedPageRevision', LockedPage.versioned_class_name + end + + def test_versioned_class + assert_equal Page::Version, Page.versioned_class + assert_equal LockedPage::LockedPageRevision, LockedPage.versioned_class + end + + def test_special_methods + assert_nothing_raised { pages(:welcome).feeling_good? } + assert_nothing_raised { pages(:welcome).versions.first.feeling_good? } + assert_nothing_raised { locked_pages(:welcome).hello_world } + assert_nothing_raised { locked_pages(:welcome).versions.first.hello_world } + end + + def test_rollback_with_version_class + p = pages(:welcome) + assert_equal 24, p.version + assert_equal 'Welcome to the weblog', p.title + + assert p.revert_to!(p.versions.first), "Couldn't revert to 23" + assert_equal 23, p.version + assert_equal 'Welcome to the weblg', p.title + end + + def test_rollback_fails_with_invalid_revision + p = locked_pages(:welcome) + assert !p.revert_to!(locked_pages(:thinking)) + end + + def test_saves_versioned_copy_with_options + p = LockedPage.create! :title => 'first title' + assert !p.new_record? + assert_equal 1, p.versions.size + assert_instance_of LockedPage.versioned_class, p.versions.first + end + + def test_rollback_with_version_number_with_options + p = locked_pages(:welcome) + assert_equal 'Welcome to the weblog', p.title + assert_equal 'LockedPage', p.versions.first.version_type + + assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23" + assert_equal 'Welcome to the weblg', p.title + assert_equal 'LockedPage', p.versions.first.version_type + end + + def test_rollback_with_version_class_with_options + p = locked_pages(:welcome) + assert_equal 'Welcome to the weblog', p.title + assert_equal 'LockedPage', p.versions.first.version_type + + assert p.revert_to!(p.versions.first), "Couldn't revert to 1" + assert_equal 'Welcome to the weblg', p.title + assert_equal 'LockedPage', p.versions.first.version_type + end + + def test_saves_versioned_copy_with_sti + p = SpecialLockedPage.create! :title => 'first title' + assert !p.new_record? + assert_equal 1, p.versions.size + assert_instance_of LockedPage.versioned_class, p.versions.first + assert_equal 'SpecialLockedPage', p.versions.first.version_type + end + + def test_rollback_with_version_number_with_sti + p = locked_pages(:thinking) + assert_equal 'So I was thinking', p.title + + assert p.revert_to!(p.versions.first.version), "Couldn't revert to 1" + assert_equal 'So I was thinking!!!', p.title + assert_equal 'SpecialLockedPage', p.versions.first.version_type + end + + def test_lock_version_works_with_versioning + p = locked_pages(:thinking) + p2 = LockedPage.find(p.id) + + p.title = 'fresh title' + p.save + assert_equal 2, p.versions.size # limit! + + assert_raises(ActiveRecord::StaleObjectError) do + p2.title = 'stale title' + p2.save + end + end + + def test_version_if_condition + p = Page.create! :title => "title" + assert_equal 1, p.version + + Page.feeling_good = false + p.save + assert_equal 1, p.version + Page.feeling_good = true + end + + def test_version_if_condition2 + # set new if condition + Page.class_eval do + def new_feeling_good() title[0..0] == 'a'; end + alias_method :old_feeling_good, :feeling_good? + alias_method :feeling_good?, :new_feeling_good + end + + p = Page.create! :title => "title" + assert_equal 1, p.version # version does not increment + assert_equal 1, p.versions(true).size + + p.update_attributes(:title => 'new title') + assert_equal 1, p.version # version does not increment + assert_equal 1, p.versions(true).size + + p.update_attributes(:title => 'a title') + assert_equal 2, p.version + assert_equal 2, p.versions(true).size + + # reset original if condition + Page.class_eval { alias_method :feeling_good?, :old_feeling_good } + end + + def test_version_if_condition_with_block + # set new if condition + old_condition = Page.version_condition + Page.version_condition = Proc.new { |page| page.title[0..0] == 'b' } + + p = Page.create! :title => "title" + assert_equal 1, p.version # version does not increment + assert_equal 1, p.versions(true).size + + p.update_attributes(:title => 'a title') + assert_equal 1, p.version # version does not increment + assert_equal 1, p.versions(true).size + + p.update_attributes(:title => 'b title') + assert_equal 2, p.version + assert_equal 2, p.versions(true).size + + # reset original if condition + Page.version_condition = old_condition + end + + def test_version_no_limit + p = Page.create! :title => "title", :body => 'first body' + p.save + p.save + 5.times do |i| + assert_page_title p, i + end + end + + def test_version_max_limit + p = LockedPage.create! :title => "title" + p.update_attributes(:title => "title1") + p.update_attributes(:title => "title2") + 5.times do |i| + assert_page_title p, i, :lock_version + assert p.versions(true).size <= 2, "locked version can only store 2 versions" + end + end + + def test_track_altered_attributes_default_value + assert !Page.track_altered_attributes + assert LockedPage.track_altered_attributes + assert SpecialLockedPage.track_altered_attributes + end + + def test_version_order + assert_equal 23, pages(:welcome).versions.first.version + assert_equal 24, pages(:welcome).versions.last.version + end + + def test_track_altered_attributes + p = LockedPage.create! :title => "title" + assert_equal 1, p.lock_version + assert_equal 1, p.versions(true).size + + p.title = 'title' + assert !p.save_version? + p.save + assert_equal 2, p.lock_version # still increments version because of optimistic locking + assert_equal 1, p.versions(true).size + + p.title = 'updated title' + assert p.save_version? + p.save + assert_equal 3, p.lock_version + assert_equal 1, p.versions(true).size # version 1 deleted + + p.title = 'updated title!' + assert p.save_version? + p.save + assert_equal 4, p.lock_version + assert_equal 2, p.versions(true).size # version 1 deleted + end + + def assert_page_title(p, i, version_field = :version) + p.title = "title#{i}" + p.save + assert_equal "title#{i}", p.title + assert_equal (i+4), p.send(version_field) + end + + def test_find_versions + assert_equal 2, locked_pages(:welcome).versions.size + assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).length + assert_equal 2, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%web%']).length + assert_equal 0, locked_pages(:thinking).versions.find(:all, :conditions => ['title LIKE ?', '%web%']).length + assert_equal 2, locked_pages(:welcome).versions.length + end + + def test_find_version + assert_equal page_versions(:welcome_1), Page.find_version(pages(:welcome).id, 23) + assert_equal page_versions(:welcome_2), Page.find_version(pages(:welcome).id, 24) + assert_equal pages(:welcome), Page.find_version(pages(:welcome).id) + + assert_equal page_versions(:welcome_1), pages(:welcome).find_version(23) + assert_equal page_versions(:welcome_2), pages(:welcome).find_version(24) + assert_equal pages(:welcome), pages(:welcome).find_version + + assert_raise(ActiveRecord::RecordNotFound) { Page.find_version(pages(:welcome).id, 1) } + assert_raise(ActiveRecord::RecordNotFound) { Page.find_version(0, 23) } + end + + def test_with_sequence + assert_equal 'widgets_seq', Widget.versioned_class.sequence_name + 3.times { Widget.create! :name => 'new widget' } + assert_equal 3, Widget.count + assert_equal 3, Widget.versioned_class.count + end + + def test_has_many_through + assert_equal [authors(:caged), authors(:mly)], pages(:welcome).authors + end + + def test_has_many_through_with_custom_association + assert_equal [authors(:caged), authors(:mly)], pages(:welcome).revisors + end + + def test_referential_integrity + pages(:welcome).destroy + assert_equal 0, Page.count + assert_equal 0, Page::Version.count + end + + def test_association_options + association = Page.reflect_on_association(:versions) + options = association.options + assert_equal :delete_all, options[:dependent] + assert_equal 'version', options[:order] + + association = Widget.reflect_on_association(:versions) + options = association.options + assert_equal :nullify, options[:dependent] + assert_equal 'version desc', options[:order] + assert_equal 'widget_id', options[:foreign_key] + + widget = Widget.create! :name => 'new widget' + assert_equal 1, Widget.count + assert_equal 1, Widget.versioned_class.count + widget.destroy + assert_equal 0, Widget.count + assert_equal 1, Widget.versioned_class.count + end + + def test_versioned_records_should_belong_to_parent + page = pages(:welcome) + page_version = page.versions.last + assert_equal page, page_version.page + end + + def test_unaltered_attributes + landmarks(:washington).attributes = landmarks(:washington).attributes.except("id") + assert !landmarks(:washington).changed? + end + + def test_unchanged_string_attributes + landmarks(:washington).attributes = landmarks(:washington).attributes.except("id").inject({}) { |params, (key, value)| params.update(key => value.to_s) } + assert !landmarks(:washington).changed? + end + + def test_should_find_earliest_version + assert_equal page_versions(:welcome_1), pages(:welcome).versions.earliest + end + + def test_should_find_latest_version + assert_equal page_versions(:welcome_2), pages(:welcome).versions.latest + end + + def test_should_find_previous_version + assert_equal page_versions(:welcome_1), page_versions(:welcome_2).previous + assert_equal page_versions(:welcome_1), pages(:welcome).versions.before(page_versions(:welcome_2)) + end + + def test_should_find_next_version + assert_equal page_versions(:welcome_2), page_versions(:welcome_1).next + assert_equal page_versions(:welcome_2), pages(:welcome).versions.after(page_versions(:welcome_1)) + end + + def test_should_find_version_count + assert_equal 24, pages(:welcome).versions_count + assert_equal 24, page_versions(:welcome_1).versions_count + assert_equal 24, page_versions(:welcome_2).versions_count + end +end \ No newline at end of file diff --git a/lib/plugins/acts_as_watchable/init.rb b/lib/plugins/acts_as_watchable/init.rb new file mode 100644 index 000000000..f39cc7d18 --- /dev/null +++ b/lib/plugins/acts_as_watchable/init.rb @@ -0,0 +1,3 @@ +# Include hook code here +require File.dirname(__FILE__) + '/lib/acts_as_watchable' +ActiveRecord::Base.send(:include, Redmine::Acts::Watchable) diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb new file mode 100644 index 000000000..36a230462 --- /dev/null +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -0,0 +1,93 @@ +# 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) + class_eval do + has_many :watchers, :as => :watchable, :dependent => :delete_all + has_many :watcher_users, :through => :watchers, :source => :user, :validate => false + + scope :watched_by, lambda { |user_id| + { :include => :watchers, + :conditions => ["#{Watcher.table_name}.user_id = ?", user_id] } + } + attr_protected :watcher_ids, :watcher_user_ids + end + send :include, Redmine::Acts::Watchable::InstanceMethods + alias_method_chain :watcher_user_ids=, :uniq_ids + 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 + ################### modified by liuping + def remove_watcher(user) + return nil unless user && user.is_a?(User) + if self.instance_of?(User) + Watcher.delete_all "watchable_type = 'Principal' AND watchable_id = #{self.id} AND user_id = #{user.id}" + else + Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" + end + end + + # Adds/removes watcher + def set_watcher(user, watching=true) + watching ? add_watcher(user) : remove_watcher(user) + end + + # Overrides watcher_user_ids= to make user_ids uniq + def watcher_user_ids_with_uniq_ids=(user_ids) + if user_ids.is_a?(Array) + user_ids = user_ids.uniq + end + send :watcher_user_ids_without_uniq_ids=, user_ids + end + + # Returns true if object is watched by +user+ + def watched_by?(user) + !!(user && self.watcher_user_ids.detect {|uid| uid == user.id }) + end + + def notified_watchers + notified = watcher_users.active + notified.reject! {|user| user.mail.blank? || user.mail_notification == 'none'} + if respond_to?(:visible?) + notified.reject! {|user| !visible?(user)} + end + notified + end + + # Returns an array of watchers' email addresses + def watcher_recipients + notified_watchers.collect(&:mail) + end + + module ClassMethods; end + end + end + end +end diff --git a/lib/plugins/awesome_nested_set/.autotest b/lib/plugins/awesome_nested_set/.autotest new file mode 100644 index 000000000..54518a40a --- /dev/null +++ b/lib/plugins/awesome_nested_set/.autotest @@ -0,0 +1,13 @@ +Autotest.add_hook :initialize do |at| + at.clear_mappings + + at.add_mapping %r%^lib/(.*)\.rb$% do |_, m| + at.files_matching %r%^test/#{m[1]}_test.rb$% + end + + at.add_mapping(%r%^test/.*\.rb$%) {|filename, _| filename } + + at.add_mapping %r%^test/fixtures/(.*)s.yml% do |_, _| + at.files_matching %r%^test/.*\.rb$% + end +end \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/.travis.yml b/lib/plugins/awesome_nested_set/.travis.yml new file mode 100644 index 000000000..179e88bdf --- /dev/null +++ b/lib/plugins/awesome_nested_set/.travis.yml @@ -0,0 +1,14 @@ +notifications: + email: + - parndt@gmail.com +env: + - DB=sqlite3 + - DB=sqlite3mem + - DB=postgresql + - DB=mysql +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - rbx-2.0 + - jruby \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/CHANGELOG b/lib/plugins/awesome_nested_set/CHANGELOG new file mode 100644 index 000000000..140164fcf --- /dev/null +++ b/lib/plugins/awesome_nested_set/CHANGELOG @@ -0,0 +1,14 @@ +2.0.2 +* Fixed deprecation warning under Rails 3.1 [Philip Arndt] +* Converted Test::Unit matchers to RSpec. [UÄ£is Ozols] +* Added inverse_of to associations to improve performance rendering trees. [Sergio Cambra] +* Added row locking and fixed some race conditions. [Markus J. Q. Roberts] + +2.0.1 +* Fixed a bug with move_to not using nested_set_scope [Andreas Sekine] + +2.0.0.pre +* Expect Rails 3 +* Changed how callbacks work. Returning false in a before_move action does not block save operations. Use a validation or exception in the callback if you need that. +* Switched to RSpec +* Remove use of Comparable diff --git a/lib/plugins/awesome_nested_set/MIT-LICENSE b/lib/plugins/awesome_nested_set/MIT-LICENSE new file mode 100644 index 000000000..7cdb82927 --- /dev/null +++ b/lib/plugins/awesome_nested_set/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2007-2011 Collective Idea + +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 --git a/lib/plugins/awesome_nested_set/README.rdoc b/lib/plugins/awesome_nested_set/README.rdoc new file mode 100644 index 000000000..6a7380b60 --- /dev/null +++ b/lib/plugins/awesome_nested_set/README.rdoc @@ -0,0 +1,100 @@ += 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 more awesome. + +Version 2 supports Rails 3. Gem versions prior to 2.0 support Rails 2. + +== 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 + + Add to your Gemfile: + + gem 'awesome_nested_set' + +== 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 for more info. + +== Protecting attributes from mass assignment + +It's generally best to "white list" the attributes that can be used in mass assignment: + + class Category < ActiveRecord::Base + acts_as_nested_set + attr_accessible :name, :parent_id + end + +If for some reason that is not possible, you will probably want to protect the lft and rgt attributes: + + class Category < ActiveRecord::Base + acts_as_nested_set + attr_protected :lft, :rgt + end + +== Conversion from other trees + +Coming from acts_as_tree or another system where you only have a parent_id? No problem. Simply add the lft & rgt fields as above, and then run + + Category.rebuild! + +Your tree will be converted to a valid nested set. Awesome! + +== 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://threebit.net/tutorials/nestedset/tutorial1.html + +== How to contribute + +If you find what you might think is a bug: + +1. Check the GitHub issue tracker to see if anyone else has had the same issue. + http://github.com/collectiveidea/awesome_nested_set/issues/ +2. If you don't see anything, create an issue with information on how to reproduce it. + +If you want to contribute an enhancement or a fix: + +1. Fork the project on github. + http://github.com/collectiveidea/awesome_nested_set/ +2. Make your changes with tests. +3. Commit the changes without making changes to the Rakefile, VERSION, or any other files that aren't related to your enhancement or fix +4. Send a pull request. + +Copyright ©2008 Collective Idea, released under the MIT license diff --git a/lib/plugins/awesome_nested_set/Rakefile b/lib/plugins/awesome_nested_set/Rakefile new file mode 100644 index 000000000..b913bc5e2 --- /dev/null +++ b/lib/plugins/awesome_nested_set/Rakefile @@ -0,0 +1,28 @@ +# -*- encoding: utf-8 -*- +$LOAD_PATH.unshift File.expand_path("../lib", __FILE__) +require 'rubygems' +require 'bundler/setup' +require 'awesome_nested_set/version' + +require "rspec/core/rake_task" +RSpec::Core::RakeTask.new(:spec) + +task :default => :spec + +task :build do + system "gem build awesome_nested_set.gemspec" +end + +task :release => :build do + system "gem push awesome_nested_set-#{ActsAsGeocodable::VERSION}.gem" +end + +require 'rdoc/task' +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 diff --git a/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec b/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec new file mode 100644 index 000000000..8e85d6733 --- /dev/null +++ b/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec @@ -0,0 +1,22 @@ +# -*- encoding: utf-8 -*- +lib = File.expand_path('../lib/', __FILE__) +$:.unshift lib unless $:.include?(lib) +require 'awesome_nested_set/version' + +Gem::Specification.new do |s| + s.name = %q{awesome_nested_set} + s.version = ::AwesomeNestedSet::VERSION + s.authors = ["Brandon Keepers", "Daniel Morrison", "Philip Arndt"] + s.description = %q{An awesome nested set implementation for Active Record} + s.email = %q{info@collectiveidea.com} + s.extra_rdoc_files = [ + "README.rdoc" + ] + s.files = Dir.glob("lib/**/*") + %w(MIT-LICENSE README.rdoc CHANGELOG) + s.homepage = %q{http://github.com/collectiveidea/awesome_nested_set} + s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"] + s.require_paths = ["lib"] + s.rubygems_version = %q{1.3.6} + s.summary = %q{An awesome nested set implementation for Active Record} + s.add_runtime_dependency 'activerecord', '>= 3.0.0' +end diff --git a/lib/plugins/awesome_nested_set/init.rb b/lib/plugins/awesome_nested_set/init.rb new file mode 100644 index 000000000..a505b6acf --- /dev/null +++ b/lib/plugins/awesome_nested_set/init.rb @@ -0,0 +1 @@ +require File.dirname(__FILE__) + '/lib/awesome_nested_set' \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb new file mode 100644 index 000000000..022044275 --- /dev/null +++ b/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb @@ -0,0 +1,7 @@ +require 'awesome_nested_set/awesome_nested_set' +ActiveRecord::Base.send :extend, CollectiveIdea::Acts::NestedSet + +if defined?(ActionView) + require 'awesome_nested_set/helper' + ActionView::Base.send :include, CollectiveIdea::Acts::NestedSet::Helper +end \ No newline at end of file diff --git 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 new file mode 100644 index 000000000..7f0b23197 --- /dev/null +++ b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb @@ -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: acts_as_nested_set :scope => [:notable_id, :notable_type] + # * +: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: acts_as_nested_set :counter_cache => :children_count + # + # 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 --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb new file mode 100644 index 000000000..bfeb18ce4 --- /dev/null +++ b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb @@ -0,0 +1,44 @@ +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) + if class_or_item.is_a? Array + items = class_or_item.reject { |e| !e.root? } + else + class_or_item = class_or_item.roots if class_or_item.is_a?(Class) + items = Array(class_or_item) + end + 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 diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb new file mode 100644 index 000000000..755256ab4 --- /dev/null +++ b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb @@ -0,0 +1,3 @@ +module AwesomeNestedSet + VERSION = '2.1.0' unless defined?(::AwesomeNestedSet::VERSION) +end diff --git a/lib/plugins/awesome_nested_set/rails/init.rb b/lib/plugins/awesome_nested_set/rails/init.rb new file mode 100644 index 000000000..e0a4e8b06 --- /dev/null +++ b/lib/plugins/awesome_nested_set/rails/init.rb @@ -0,0 +1,13 @@ +require 'awesome_nested_set/compatability' +require 'awesome_nested_set' + +ActiveRecord::Base.class_eval do + include CollectiveIdea::Acts::NestedSet +end + +if defined?(ActionView) + require 'awesome_nested_set/helper' + ActionView::Base.class_eval do + include CollectiveIdea::Acts::NestedSet::Helper + end +end \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb b/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb new file mode 100644 index 000000000..1cca71ba8 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb @@ -0,0 +1,67 @@ +require 'spec_helper' + +describe "Helper" do + include CollectiveIdea::Acts::NestedSet::Helper + + before(:all) do + self.class.fixtures :categories + end + + describe "nested_set_options" do + it "test_nested_set_options" do + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 2', 3], + ['-- Child 2.1', 4], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category) do |c| + "#{'-' * c.level} #{c.name}" + end + actual.should == expected + end + + it "test_nested_set_options_with_mover" do + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category, categories(:child_2)) do |c| + "#{'-' * c.level} #{c.name}" + end + actual.should == expected + end + + it "test_nested_set_options_with_array_as_argument_without_mover" do + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 2', 3], + ['-- Child 2.1', 4], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category.all) do |c| + "#{'-' * c.level} #{c.name}" + end + actual.should == expected + end + + it "test_nested_set_options_with_array_as_argument_with_mover" do + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category.all, categories(:child_2)) do |c| + "#{'-' * c.level} #{c.name}" + end + actual.should == expected + end + end +end diff --git a/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb b/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb new file mode 100644 index 000000000..692b123a5 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb @@ -0,0 +1,841 @@ +require 'spec_helper' + +describe "AwesomeNestedSet" do + before(:all) do + self.class.fixtures :categories, :departments, :notes, :things, :brokens + end + + describe "defaults" do + it "should have left_column_default" do + Default.acts_as_nested_set_options[:left_column].should == 'lft' + end + + it "should have right_column_default" do + Default.acts_as_nested_set_options[:right_column].should == 'rgt' + end + + it "should have parent_column_default" do + Default.acts_as_nested_set_options[:parent_column].should == 'parent_id' + end + + it "should have scope_default" do + Default.acts_as_nested_set_options[:scope].should be_nil + end + + it "should have left_column_name" do + Default.left_column_name.should == 'lft' + Default.new.left_column_name.should == 'lft' + RenamedColumns.left_column_name.should == 'red' + RenamedColumns.new.left_column_name.should == 'red' + end + + it "should have right_column_name" do + Default.right_column_name.should == 'rgt' + Default.new.right_column_name.should == 'rgt' + RenamedColumns.right_column_name.should == 'black' + RenamedColumns.new.right_column_name.should == 'black' + end + + it "should have parent_column_name" do + Default.parent_column_name.should == 'parent_id' + Default.new.parent_column_name.should == 'parent_id' + RenamedColumns.parent_column_name.should == 'mother_id' + RenamedColumns.new.parent_column_name.should == 'mother_id' + end + end + + it "creation_with_altered_column_names" do + lambda { + RenamedColumns.create!() + }.should_not raise_exception + end + + it "creation when existing record has nil left column" do + assert_nothing_raised do + Broken.create! + end + end + + it "quoted_left_column_name" do + quoted = Default.connection.quote_column_name('lft') + Default.quoted_left_column_name.should == quoted + Default.new.quoted_left_column_name.should == quoted + end + + it "quoted_right_column_name" do + quoted = Default.connection.quote_column_name('rgt') + Default.quoted_right_column_name.should == quoted + Default.new.quoted_right_column_name.should == quoted + end + + it "left_column_protected_from_assignment" do + lambda { + Category.new.lft = 1 + }.should raise_exception(ActiveRecord::ActiveRecordError) + end + + it "right_column_protected_from_assignment" do + lambda { + Category.new.rgt = 1 + }.should raise_exception(ActiveRecord::ActiveRecordError) + end + + it "scoped_appends_id" do + ScopedCategory.acts_as_nested_set_options[:scope].should == :organization_id + end + + it "roots_class_method" do + Category.roots.should == Category.find_all_by_parent_id(nil) + end + + it "root_class_method" do + Category.root.should == categories(:top_level) + end + + it "root" do + categories(:child_3).root.should == categories(:top_level) + end + + it "root?" do + categories(:top_level).root?.should be_true + categories(:top_level_2).root?.should be_true + end + + it "leaves_class_method" do + Category.find(:all, :conditions => "#{Category.right_column_name} - #{Category.left_column_name} = 1").should == Category.leaves + Category.leaves.count.should == 4 + Category.leaves.should include(categories(:child_1)) + Category.leaves.should include(categories(:child_2_1)) + Category.leaves.should include(categories(:child_3)) + Category.leaves.should include(categories(:top_level_2)) + end + + it "leaf" do + categories(:child_1).leaf?.should be_true + categories(:child_2_1).leaf?.should be_true + categories(:child_3).leaf?.should be_true + categories(:top_level_2).leaf?.should be_true + + categories(:top_level).leaf?.should be_false + categories(:child_2).leaf?.should be_false + Category.new.leaf?.should be_false + end + + + it "parent" do + categories(:child_2_1).parent.should == categories(:child_2) + end + + it "self_and_ancestors" do + child = categories(:child_2_1) + self_and_ancestors = [categories(:top_level), categories(:child_2), child] + self_and_ancestors.should == child.self_and_ancestors + end + + it "ancestors" do + child = categories(:child_2_1) + ancestors = [categories(:top_level), categories(:child_2)] + ancestors.should == child.ancestors + end + + it "self_and_siblings" do + child = categories(:child_2) + self_and_siblings = [categories(:child_1), child, categories(:child_3)] + self_and_siblings.should == child.self_and_siblings + lambda do + tops = [categories(:top_level), categories(:top_level_2)] + assert_equal tops, categories(:top_level).self_and_siblings + end.should_not raise_exception + end + + it "siblings" do + child = categories(:child_2) + siblings = [categories(:child_1), categories(:child_3)] + siblings.should == child.siblings + end + + it "leaves" do + leaves = [categories(:child_1), categories(:child_2_1), categories(:child_3)] + categories(:top_level).leaves.should == leaves + end + + it "level" do + categories(:top_level).level.should == 0 + categories(:child_1).level.should == 1 + categories(:child_2_1).level.should == 2 + end + + it "has_children?" do + categories(:child_2_1).children.empty?.should be_true + categories(:child_2).children.empty?.should be_false + categories(:top_level).children.empty?.should be_false + end + + it "self_and_descendents" do + parent = categories(:top_level) + self_and_descendants = [parent, categories(:child_1), categories(:child_2), + categories(:child_2_1), categories(:child_3)] + self_and_descendants.should == parent.self_and_descendants + self_and_descendants.count.should == parent.self_and_descendants.count + end + + it "descendents" do + 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 + + lawyers.children.size.should == 1 + us.children.size.should == 1 + lawyers.descendants.size.should == 2 + end + + it "self_and_descendents" do + parent = categories(:top_level) + descendants = [categories(:child_1), categories(:child_2), + categories(:child_2_1), categories(:child_3)] + descendants.should == parent.descendants + end + + it "children" do + category = categories(:top_level) + category.children.each {|c| category.id.should == c.parent_id } + end + + it "order_of_children" do + categories(:child_2).move_left + categories(:child_2).should == categories(:top_level).children[0] + categories(:child_1).should == categories(:top_level).children[1] + categories(:child_3).should == categories(:top_level).children[2] + end + + it "is_or_is_ancestor_of?" do + categories(:top_level).is_or_is_ancestor_of?(categories(:child_1)).should be_true + categories(:top_level).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true + categories(:child_2).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true + categories(:child_2_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false + categories(:child_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false + categories(:child_1).is_or_is_ancestor_of?(categories(:child_1)).should be_true + end + + it "is_ancestor_of?" do + categories(:top_level).is_ancestor_of?(categories(:child_1)).should be_true + categories(:top_level).is_ancestor_of?(categories(:child_2_1)).should be_true + categories(:child_2).is_ancestor_of?(categories(:child_2_1)).should be_true + categories(:child_2_1).is_ancestor_of?(categories(:child_2)).should be_false + categories(:child_1).is_ancestor_of?(categories(:child_2)).should be_false + categories(:child_1).is_ancestor_of?(categories(:child_1)).should be_false + end + + it "is_or_is_ancestor_of_with_scope" do + root = ScopedCategory.root + child = root.children.first + root.is_or_is_ancestor_of?(child).should be_true + child.update_attribute :organization_id, 'different' + root.is_or_is_ancestor_of?(child).should be_false + end + + it "is_or_is_descendant_of?" do + categories(:child_1).is_or_is_descendant_of?(categories(:top_level)).should be_true + categories(:child_2_1).is_or_is_descendant_of?(categories(:top_level)).should be_true + categories(:child_2_1).is_or_is_descendant_of?(categories(:child_2)).should be_true + categories(:child_2).is_or_is_descendant_of?(categories(:child_2_1)).should be_false + categories(:child_2).is_or_is_descendant_of?(categories(:child_1)).should be_false + categories(:child_1).is_or_is_descendant_of?(categories(:child_1)).should be_true + end + + it "is_descendant_of?" do + categories(:child_1).is_descendant_of?(categories(:top_level)).should be_true + categories(:child_2_1).is_descendant_of?(categories(:top_level)).should be_true + categories(:child_2_1).is_descendant_of?(categories(:child_2)).should be_true + categories(:child_2).is_descendant_of?(categories(:child_2_1)).should be_false + categories(:child_2).is_descendant_of?(categories(:child_1)).should be_false + categories(:child_1).is_descendant_of?(categories(:child_1)).should be_false + end + + it "is_or_is_descendant_of_with_scope" do + root = ScopedCategory.root + child = root.children.first + child.is_or_is_descendant_of?(root).should be_true + child.update_attribute :organization_id, 'different' + child.is_or_is_descendant_of?(root).should be_false + end + + it "same_scope?" do + root = ScopedCategory.root + child = root.children.first + child.same_scope?(root).should be_true + child.update_attribute :organization_id, 'different' + child.same_scope?(root).should be_false + end + + it "left_sibling" do + categories(:child_1).should == categories(:child_2).left_sibling + categories(:child_2).should == categories(:child_3).left_sibling + end + + it "left_sibling_of_root" do + categories(:top_level).left_sibling.should be_nil + end + + it "left_sibling_without_siblings" do + categories(:child_2_1).left_sibling.should be_nil + end + + it "left_sibling_of_leftmost_node" do + categories(:child_1).left_sibling.should be_nil + end + + it "right_sibling" do + categories(:child_3).should == categories(:child_2).right_sibling + categories(:child_2).should == categories(:child_1).right_sibling + end + + it "right_sibling_of_root" do + categories(:top_level_2).should == categories(:top_level).right_sibling + categories(:top_level_2).right_sibling.should be_nil + end + + it "right_sibling_without_siblings" do + categories(:child_2_1).right_sibling.should be_nil + end + + it "right_sibling_of_rightmost_node" do + categories(:child_3).right_sibling.should be_nil + end + + it "move_left" do + categories(:child_2).move_left + categories(:child_2).left_sibling.should be_nil + categories(:child_1).should == categories(:child_2).right_sibling + Category.valid?.should be_true + end + + it "move_right" do + categories(:child_2).move_right + categories(:child_2).right_sibling.should be_nil + categories(:child_3).should == categories(:child_2).left_sibling + Category.valid?.should be_true + end + + it "move_to_left_of" do + categories(:child_3).move_to_left_of(categories(:child_1)) + categories(:child_3).left_sibling.should be_nil + categories(:child_1).should == categories(:child_3).right_sibling + Category.valid?.should be_true + end + + it "move_to_right_of" do + categories(:child_1).move_to_right_of(categories(:child_3)) + categories(:child_1).right_sibling.should be_nil + categories(:child_3).should == categories(:child_1).left_sibling + Category.valid?.should be_true + end + + it "move_to_root" do + categories(:child_2).move_to_root + categories(:child_2).parent.should be_nil + categories(:child_2).level.should == 0 + categories(:child_2_1).level.should == 1 + categories(:child_2).left.should == 1 + categories(:child_2).right.should == 4 + Category.valid?.should be_true + end + + it "move_to_child_of" do + categories(:child_1).move_to_child_of(categories(:child_3)) + categories(:child_3).id.should == categories(:child_1).parent_id + Category.valid?.should be_true + end + + it "move_to_child_of_appends_to_end" do + child = Category.create! :name => 'New Child' + child.move_to_child_of categories(:top_level) + child.should == categories(:top_level).children.last + end + + it "subtree_move_to_child_of" do + categories(:child_2).left.should == 4 + categories(:child_2).right.should == 7 + + categories(:child_1).left.should == 2 + categories(:child_1).right.should == 3 + + categories(:child_2).move_to_child_of(categories(:child_1)) + Category.valid?.should be_true + categories(:child_1).id.should == categories(:child_2).parent_id + + categories(:child_2).left.should == 3 + categories(:child_2).right.should == 6 + categories(:child_1).left.should == 2 + categories(:child_1).right.should == 7 + end + + it "slightly_difficult_move_to_child_of" do + categories(:top_level_2).left.should == 11 + categories(:top_level_2).right.should == 12 + + # create a new top-level node and move single-node top-level tree inside it. + new_top = Category.create(:name => 'New Top') + new_top.left.should == 13 + new_top.right.should == 14 + + categories(:top_level_2).move_to_child_of(new_top) + + Category.valid?.should be_true + new_top.id.should == categories(:top_level_2).parent_id + + categories(:top_level_2).left.should == 12 + categories(:top_level_2).right.should == 13 + new_top.left.should == 11 + new_top.right.should == 14 + end + + it "difficult_move_to_child_of" do + categories(:top_level).left.should == 1 + categories(:top_level).right.should == 10 + categories(:child_2_1).left.should == 5 + categories(:child_2_1).right.should == 6 + + # 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 + Category.valid?.should be_true + new_top.id.should == categories(:top_level).parent_id + + categories(:top_level).left.should == 4 + categories(:top_level).right.should == 13 + categories(:child_2_1).left.should == 8 + categories(:child_2_1).right.should == 9 + end + + #rebuild swaps the position of the 2 children when added using move_to_child twice onto same parent + it "move_to_child_more_than_once_per_parent_rebuild" do + 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! + + Category.roots.last.to_text.should == output + end + + # doing move_to_child twice onto same parent from the furthest right first + it "move_to_child_more_than_once_per_parent_outside_in" do + 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! + + Category.roots.last.to_text.should == output + end + + it "should be able to rebuild without validating each record" do + 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 + + root2.name = nil + root2.save!(:validate => false) + + output = Category.roots.last.to_text + Category.update_all('lft = null, rgt = null') + Category.rebuild!(false) + + Category.roots.last.to_text.should == output + end + + it "valid_with_null_lefts" do + Category.valid?.should be_true + Category.update_all('lft = null') + Category.valid?.should be_false + end + + it "valid_with_null_rights" do + Category.valid?.should be_true + Category.update_all('rgt = null') + Category.valid?.should be_false + end + + it "valid_with_missing_intermediate_node" do + # Even though child_2_1 will still exist, it is a sign of a sloppy delete, not an invalid tree. + Category.valid?.should be_true + Category.delete(categories(:child_2).id) + Category.valid?.should be_true + end + + it "valid_with_overlapping_and_rights" do + Category.valid?.should be_true + categories(:top_level_2)['lft'] = 0 + categories(:top_level_2).save + Category.valid?.should be_false + end + + it "rebuild" do + Category.valid?.should be_true + before_text = Category.root.to_text + Category.update_all('lft = null, rgt = null') + Category.rebuild! + Category.valid?.should be_true + before_text.should == Category.root.to_text + end + + it "move_possible_for_sibling" do + categories(:child_2).move_possible?(categories(:child_1)).should be_true + end + + it "move_not_possible_to_self" do + categories(:top_level).move_possible?(categories(:top_level)).should be_false + end + + it "move_not_possible_to_parent" do + categories(:top_level).descendants.each do |descendant| + categories(:top_level).move_possible?(descendant).should be_false + descendant.move_possible?(categories(:top_level)).should be_true + end + end + + it "is_or_is_ancestor_of?" do + [:child_1, :child_2, :child_2_1, :child_3].each do |c| + categories(:top_level).is_or_is_ancestor_of?(categories(c)).should be_true + end + categories(:top_level).is_or_is_ancestor_of?(categories(:top_level_2)).should be_false + end + + it "left_and_rights_valid_with_blank_left" do + Category.left_and_rights_valid?.should be_true + categories(:child_2)[:lft] = nil + categories(:child_2).save(:validate => false) + Category.left_and_rights_valid?.should be_false + end + + it "left_and_rights_valid_with_blank_right" do + Category.left_and_rights_valid?.should be_true + categories(:child_2)[:rgt] = nil + categories(:child_2).save(:validate => false) + Category.left_and_rights_valid?.should be_false + end + + it "left_and_rights_valid_with_equal" do + Category.left_and_rights_valid?.should be_true + categories(:top_level_2)[:lft] = categories(:top_level_2)[:rgt] + categories(:top_level_2).save(:validate => false) + Category.left_and_rights_valid?.should be_false + end + + it "left_and_rights_valid_with_left_equal_to_parent" do + Category.left_and_rights_valid?.should be_true + categories(:child_2)[:lft] = categories(:top_level)[:lft] + categories(:child_2).save(:validate => false) + Category.left_and_rights_valid?.should be_false + end + + it "left_and_rights_valid_with_right_equal_to_parent" do + Category.left_and_rights_valid?.should be_true + categories(:child_2)[:rgt] = categories(:top_level)[:rgt] + categories(:child_2).save(:validate => false) + Category.left_and_rights_valid?.should be_false + end + + it "moving_dirty_objects_doesnt_invalidate_tree" do + r1 = Category.create :name => "Test 1" + r2 = Category.create :name => "Test 2" + r3 = Category.create :name => "Test 3" + r4 = Category.create :name => "Test 4" + nodes = [r1, r2, r3, r4] + + r2.move_to_child_of(r1) + Category.valid?.should be_true + + r3.move_to_child_of(r1) + Category.valid?.should be_true + + r4.move_to_child_of(r2) + Category.valid?.should be_true + end + + it "multi_scoped_no_duplicates_for_columns?" do + lambda { + Note.no_duplicates_for_columns? + }.should_not raise_exception + end + + it "multi_scoped_all_roots_valid?" do + lambda { + Note.all_roots_valid? + }.should_not raise_exception + end + + it "multi_scoped" do + 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') + + [note1, note2].should == note1.self_and_siblings + [note3].should == note3.self_and_siblings + end + + it "multi_scoped_rebuild" do + 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! + + Note.roots.find_by_body('A').should == root + [child1, child2].should == Note.roots.find_by_body('A').children + end + + it "same_scope_with_multi_scopes" do + lambda { + notes(:scope1).same_scope?(notes(:child_1)) + }.should_not raise_exception + notes(:scope1).same_scope?(notes(:child_1)).should be_true + notes(:child_1).same_scope?(notes(:scope1)).should be_true + notes(:scope1).same_scope?(notes(:scope2)).should be_false + end + + it "quoting_of_multi_scope_column_names" do + ["\"notable_id\"", "\"notable_type\""].should == Note.quoted_scope_column_names + end + + it "equal_in_same_scope" do + notes(:scope1).should == notes(:scope1) + notes(:scope1).should_not == notes(:child_1) + end + + it "equal_in_different_scopes" do + notes(:scope1).should_not == notes(:scope2) + end + + it "delete_does_not_invalidate" do + Category.acts_as_nested_set_options[:dependent] = :delete + categories(:child_2).destroy + Category.valid?.should be_true + end + + it "destroy_does_not_invalidate" do + Category.acts_as_nested_set_options[:dependent] = :destroy + categories(:child_2).destroy + Category.valid?.should be_true + end + + it "destroy_multiple_times_does_not_invalidate" do + Category.acts_as_nested_set_options[:dependent] = :destroy + categories(:child_2).destroy + categories(:child_2).destroy + Category.valid?.should be_true + end + + it "assigning_parent_id_on_create" do + category = Category.create!(:name => "Child", :parent_id => categories(:child_2).id) + categories(:child_2).should == category.parent + categories(:child_2).id.should == category.parent_id + category.left.should_not be_nil + category.right.should_not be_nil + Category.valid?.should be_true + end + + it "assigning_parent_on_create" do + category = Category.create!(:name => "Child", :parent => categories(:child_2)) + categories(:child_2).should == category.parent + categories(:child_2).id.should == category.parent_id + category.left.should_not be_nil + category.right.should_not be_nil + Category.valid?.should be_true + end + + it "assigning_parent_id_to_nil_on_create" do + category = Category.create!(:name => "New Root", :parent_id => nil) + category.parent.should be_nil + category.parent_id.should be_nil + category.left.should_not be_nil + category.right.should_not be_nil + Category.valid?.should be_true + end + + it "assigning_parent_id_on_update" do + category = categories(:child_2_1) + category.parent_id = categories(:child_3).id + category.save + category.reload + categories(:child_3).reload + categories(:child_3).should == category.parent + categories(:child_3).id.should == category.parent_id + Category.valid?.should be_true + end + + it "assigning_parent_on_update" do + category = categories(:child_2_1) + category.parent = categories(:child_3) + category.save + category.reload + categories(:child_3).reload + categories(:child_3).should == category.parent + categories(:child_3).id.should == category.parent_id + Category.valid?.should be_true + end + + it "assigning_parent_id_to_nil_on_update" do + category = categories(:child_2_1) + category.parent_id = nil + category.save + category.parent.should be_nil + category.parent_id.should be_nil + Category.valid?.should be_true + end + + it "creating_child_from_parent" do + category = categories(:child_2).children.create!(:name => "Child") + categories(:child_2).should == category.parent + categories(:child_2).id.should == category.parent_id + category.left.should_not be_nil + category.right.should_not be_nil + Category.valid?.should be_true + end + + def check_structure(entries, structure) + structure = structure.dup + Category.each_with_level(entries) do |category, level| + expected_level, expected_name = structure.shift + expected_name.should == category.name + expected_level.should == level + end + end + + it "each_with_level" do + levels = [ + [0, "Top Level"], + [1, "Child 1"], + [1, "Child 2"], + [2, "Child 2.1"], + [1, "Child 3" ]] + + check_structure(Category.root.self_and_descendants, levels) + + # test some deeper structures + category = Category.find_by_name("Child 1") + c1 = Category.new(:name => "Child 1.1") + c2 = Category.new(:name => "Child 1.1.1") + c3 = Category.new(:name => "Child 1.1.1.1") + c4 = Category.new(:name => "Child 1.2") + [c1, c2, c3, c4].each(&:save!) + + c1.move_to_child_of(category) + c2.move_to_child_of(c1) + c3.move_to_child_of(c2) + c4.move_to_child_of(category) + + levels = [ + [0, "Top Level"], + [1, "Child 1"], + [2, "Child 1.1"], + [3, "Child 1.1.1"], + [4, "Child 1.1.1.1"], + [2, "Child 1.2"], + [1, "Child 2"], + [2, "Child 2.1"], + [1, "Child 3" ]] + + check_structure(Category.root.self_and_descendants, levels) + end + + it "should not error on a model with attr_accessible" do + model = Class.new(ActiveRecord::Base) + model.table_name = 'categories' + model.attr_accessible :name + lambda { + model.acts_as_nested_set + model.new(:name => 'foo') + }.should_not raise_exception + end + + describe "before_move_callback" do + it "should fire the callback" do + categories(:child_2).should_receive(:custom_before_move) + categories(:child_2).move_to_root + end + + it "should stop move when callback returns false" do + Category.test_allows_move = false + categories(:child_3).move_to_root.should be_false + categories(:child_3).root?.should be_false + end + + it "should not halt save actions" do + Category.test_allows_move = false + categories(:child_3).parent_id = nil + categories(:child_3).save.should be_true + end + end + + describe "counter_cache" do + + it "should allow use of a counter cache for children" do + note1 = things(:parent1) + note1.children.count.should == 2 + end + + it "should increment the counter cache on create" do + note1 = things(:parent1) + note1.children.count.should == 2 + note1[:children_count].should == 2 + note1.children.create :body => 'Child 3' + note1.children.count.should == 3 + note1.reload + note1[:children_count].should == 3 + end + + it "should decrement the counter cache on destroy" do + note1 = things(:parent1) + note1.children.count.should == 2 + note1[:children_count].should == 2 + note1.children.last.destroy + note1.children.count.should == 1 + note1.reload + note1[:children_count].should == 1 + end + end + + describe "association callbacks on children" do + it "should call the appropriate callbacks on the children :has_many association " do + root = DefaultWithCallbacks.create + root.should_not be_new_record + + child = root.children.build + + root.before_add.should == child + root.after_add.should == child + + root.before_remove.should_not == child + root.after_remove.should_not == child + + child.save.should be_true + root.children.delete(child).should be_true + + root.before_remove.should == child + root.after_remove.should == child + end + end +end diff --git a/lib/plugins/awesome_nested_set/spec/db/database.yml b/lib/plugins/awesome_nested_set/spec/db/database.yml new file mode 100644 index 000000000..eaa5ed3a0 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/db/database.yml @@ -0,0 +1,18 @@ +sqlite3: + adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3 + database: awesome_nested_set.sqlite3.db +sqlite3mem: + adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3 + database: ":memory:" +postgresql: + adapter: postgresql + username: postgres + password: postgres + database: awesome_nested_set_plugin_test + min_messages: ERROR +mysql: + adapter: mysql2 + host: localhost + username: root + password: + database: awesome_nested_set_plugin_test \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/db/schema.rb b/lib/plugins/awesome_nested_set/spec/db/schema.rb new file mode 100644 index 000000000..dcdcde814 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/db/schema.rb @@ -0,0 +1,45 @@ +ActiveRecord::Schema.define(:version => 0) do + + create_table :categories, :force => true do |t| + t.column :name, :string + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + t.column :organization_id, :integer + end + + create_table :departments, :force => true do |t| + t.column :name, :string + end + + create_table :notes, :force => true do |t| + t.column :body, :text + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + t.column :notable_id, :integer + t.column :notable_type, :string + end + + create_table :renamed_columns, :force => true do |t| + t.column :name, :string + t.column :mother_id, :integer + t.column :red, :integer + t.column :black, :integer + end + + create_table :things, :force => true do |t| + t.column :body, :text + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + t.column :children_count, :integer + end + + create_table :brokens, :force => true do |t| + t.column :name, :string + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + end +end diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml b/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml new file mode 100644 index 000000000..3cb6ce915 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml @@ -0,0 +1,3 @@ +one: + id: 1 + name: One \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml b/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml new file mode 100644 index 000000000..bc8e078e8 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml @@ -0,0 +1,34 @@ +top_level: + id: 1 + name: Top Level + lft: 1 + rgt: 10 +child_1: + id: 2 + name: Child 1 + parent_id: 1 + lft: 2 + rgt: 3 +child_2: + id: 3 + name: Child 2 + parent_id: 1 + lft: 4 + rgt: 7 +child_2_1: + id: 4 + name: Child 2.1 + parent_id: 3 + lft: 5 + rgt: 6 +child_3: + id: 5 + name: Child 3 + parent_id: 1 + lft: 8 + rgt: 9 +top_level_2: + id: 6 + name: Top Level 2 + lft: 11 + rgt: 12 diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml b/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml new file mode 100644 index 000000000..e50a944f1 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml @@ -0,0 +1,3 @@ +top: + id: 1 + name: Top \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml b/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml new file mode 100644 index 000000000..004a5335a --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml @@ -0,0 +1,38 @@ +scope1: + id: 1 + body: Top Level + lft: 1 + rgt: 10 + notable_id: 1 + notable_type: Category +child_1: + id: 2 + body: Child 1 + parent_id: 1 + lft: 2 + rgt: 3 + notable_id: 1 + notable_type: Category +child_2: + id: 3 + body: Child 2 + parent_id: 1 + lft: 4 + rgt: 7 + notable_id: 1 + notable_type: Category +child_3: + id: 4 + body: Child 3 + parent_id: 1 + lft: 8 + rgt: 9 + notable_id: 1 + notable_type: Category +scope2: + id: 5 + body: Top Level 2 + lft: 1 + rgt: 2 + notable_id: 1 + notable_type: Departments diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/things.yml b/lib/plugins/awesome_nested_set/spec/fixtures/things.yml new file mode 100644 index 000000000..207a682ed --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/fixtures/things.yml @@ -0,0 +1,27 @@ +parent1: + id: 1 + body: Top Level + lft: 1 + rgt: 10 + children_count: 2 +child_1: + id: 2 + body: Child 1 + parent_id: 1 + lft: 2 + rgt: 3 + children_count: 0 +child_2: + id: 3 + body: Child 2 + parent_id: 1 + lft: 4 + rgt: 7 + children_count: 0 +child_2_1: + id: 4 + body: Child 2.1 + parent_id: 3 + lft: 8 + rgt: 9 + children_count: 0 diff --git a/lib/plugins/awesome_nested_set/spec/spec_helper.rb b/lib/plugins/awesome_nested_set/spec/spec_helper.rb new file mode 100644 index 000000000..c9cf43d88 --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/spec_helper.rb @@ -0,0 +1,32 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') +plugin_test_dir = File.dirname(__FILE__) + +require 'rubygems' +require 'bundler/setup' + +require 'rspec' +require 'logger' + +require 'active_support' +require 'active_model' +require 'active_record' +require 'action_controller' + +require 'awesome_nested_set' + +ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log") + +require 'yaml' +require 'erb' +ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir + "/db/database.yml")).result) +ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem") +ActiveRecord::Migration.verbose = false +load(File.join(plugin_test_dir, "db", "schema.rb")) + +require 'support/models' + +require 'rspec/rails' +RSpec.configure do |config| + config.fixture_path = "#{plugin_test_dir}/fixtures" + config.use_transactional_fixtures = true +end diff --git a/lib/plugins/awesome_nested_set/spec/support/models.rb b/lib/plugins/awesome_nested_set/spec/support/models.rb new file mode 100644 index 000000000..fadb0dc0b --- /dev/null +++ b/lib/plugins/awesome_nested_set/spec/support/models.rb @@ -0,0 +1,72 @@ +class Note < ActiveRecord::Base + acts_as_nested_set :scope => [:notable_id, :notable_type] +end + +class Default < ActiveRecord::Base + self.table_name = 'categories' + acts_as_nested_set +end + +class ScopedCategory < ActiveRecord::Base + self.table_name = 'categories' + acts_as_nested_set :scope => :organization +end + +class RenamedColumns < ActiveRecord::Base + acts_as_nested_set :parent_column => 'mother_id', :left_column => 'red', :right_column => 'black' +end + +class Category < ActiveRecord::Base + acts_as_nested_set + + validates_presence_of :name + + # Setup a callback that we can switch to true or false per-test + set_callback :move, :before, :custom_before_move + cattr_accessor :test_allows_move + @@test_allows_move = true + def custom_before_move + @@test_allows_move + end + + def to_s + name + end + + def recurse &block + block.call self, lambda{ + self.children.each do |child| + child.recurse &block + end + } + end +end + +class Thing < ActiveRecord::Base + acts_as_nested_set :counter_cache => 'children_count' +end + +class DefaultWithCallbacks < ActiveRecord::Base + + self.table_name = 'categories' + + attr_accessor :before_add, :after_add, :before_remove, :after_remove + + acts_as_nested_set :before_add => :do_before_add_stuff, + :after_add => :do_after_add_stuff, + :before_remove => :do_before_remove_stuff, + :after_remove => :do_after_remove_stuff + + private + + [ :before_add, :after_add, :before_remove, :after_remove ].each do |hook_name| + define_method "do_#{hook_name}_stuff" do |child_node| + self.send("#{hook_name}=", child_node) + end + end + +end + +class Broken < ActiveRecord::Base + acts_as_nested_set +end \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb b/lib/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb new file mode 100644 index 000000000..6122a0e60 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb @@ -0,0 +1,41 @@ +require File.dirname(__FILE__) + '/../test_helper' + +module CollectiveIdea + module Acts #:nodoc: + module NestedSet #:nodoc: + class AwesomeNestedSetTest < Test::Unit::TestCase + include Helper + fixtures :categories + + def test_nested_set_options + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 2', 3], + ['-- Child 2.1', 4], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category) do |c| + "#{'-' * c.level} #{c.name}" + end + assert_equal expected, actual + end + + def test_nested_set_options_with_mover + expected = [ + [" Top Level", 1], + ["- Child 1", 2], + ['- Child 3', 5], + [" Top Level 2", 6] + ] + actual = nested_set_options(Category, categories(:child_2)) do |c| + "#{'-' * c.level} #{c.name}" + end + assert_equal expected, actual + end + + end + end + end +end \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/test/awesome_nested_set_test.rb b/lib/plugins/awesome_nested_set/test/awesome_nested_set_test.rb new file mode 100644 index 000000000..9f94b43d8 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/awesome_nested_set_test.rb @@ -0,0 +1,603 @@ +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 + self.table_name = 'categories' + end + class Scoped < ActiveRecord::Base + acts_as_nested_set :scope => :organization + self.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 --git a/lib/plugins/awesome_nested_set/test/db/database.yml b/lib/plugins/awesome_nested_set/test/db/database.yml new file mode 100644 index 000000000..9281236d2 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/db/database.yml @@ -0,0 +1,18 @@ +sqlite3: + adapter: sqlite3 + dbfile: awesome_nested_set.sqlite3.db +sqlite3mem: + :adapter: sqlite3 + :dbfile: ":memory:" +postgresql: + :adapter: postgresql + :username: postgres + :password: postgres + :database: awesome_nested_set_plugin_test + :min_messages: ERROR +mysql: + :adapter: mysql + :host: localhost + :username: root + :password: + :database: awesome_nested_set_plugin_test \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/test/db/schema.rb b/lib/plugins/awesome_nested_set/test/db/schema.rb new file mode 100644 index 000000000..bbed1eb16 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/db/schema.rb @@ -0,0 +1,23 @@ +ActiveRecord::Schema.define(:version => 0) do + + create_table :categories, :force => true do |t| + t.column :name, :string + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + t.column :organization_id, :integer + end + + create_table :departments, :force => true do |t| + t.column :name, :string + end + + create_table :notes, :force => true do |t| + t.column :body, :text + t.column :parent_id, :integer + t.column :lft, :integer + t.column :rgt, :integer + t.column :notable_id, :integer + t.column :notable_type, :string + end +end diff --git a/lib/plugins/awesome_nested_set/test/fixtures/categories.yml b/lib/plugins/awesome_nested_set/test/fixtures/categories.yml new file mode 100644 index 000000000..bc8e078e8 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/fixtures/categories.yml @@ -0,0 +1,34 @@ +top_level: + id: 1 + name: Top Level + lft: 1 + rgt: 10 +child_1: + id: 2 + name: Child 1 + parent_id: 1 + lft: 2 + rgt: 3 +child_2: + id: 3 + name: Child 2 + parent_id: 1 + lft: 4 + rgt: 7 +child_2_1: + id: 4 + name: Child 2.1 + parent_id: 3 + lft: 5 + rgt: 6 +child_3: + id: 5 + name: Child 3 + parent_id: 1 + lft: 8 + rgt: 9 +top_level_2: + id: 6 + name: Top Level 2 + lft: 11 + rgt: 12 diff --git a/lib/plugins/awesome_nested_set/test/fixtures/category.rb b/lib/plugins/awesome_nested_set/test/fixtures/category.rb new file mode 100644 index 000000000..506b0dac5 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/fixtures/category.rb @@ -0,0 +1,15 @@ +class Category < ActiveRecord::Base + acts_as_nested_set + + def to_s + name + end + + def recurse &block + block.call self, lambda{ + self.children.each do |child| + child.recurse &block + end + } + end +end \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/test/fixtures/departments.yml b/lib/plugins/awesome_nested_set/test/fixtures/departments.yml new file mode 100644 index 000000000..e50a944f1 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/fixtures/departments.yml @@ -0,0 +1,3 @@ +top: + id: 1 + name: Top \ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/test/fixtures/notes.yml b/lib/plugins/awesome_nested_set/test/fixtures/notes.yml new file mode 100644 index 000000000..004a5335a --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/fixtures/notes.yml @@ -0,0 +1,38 @@ +scope1: + id: 1 + body: Top Level + lft: 1 + rgt: 10 + notable_id: 1 + notable_type: Category +child_1: + id: 2 + body: Child 1 + parent_id: 1 + lft: 2 + rgt: 3 + notable_id: 1 + notable_type: Category +child_2: + id: 3 + body: Child 2 + parent_id: 1 + lft: 4 + rgt: 7 + notable_id: 1 + notable_type: Category +child_3: + id: 4 + body: Child 3 + parent_id: 1 + lft: 8 + rgt: 9 + notable_id: 1 + notable_type: Category +scope2: + id: 5 + body: Top Level 2 + lft: 1 + rgt: 2 + notable_id: 1 + notable_type: Departments diff --git a/lib/plugins/awesome_nested_set/test/test_helper.rb b/lib/plugins/awesome_nested_set/test/test_helper.rb new file mode 100644 index 000000000..693982236 --- /dev/null +++ b/lib/plugins/awesome_nested_set/test/test_helper.rb @@ -0,0 +1,31 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') +plugin_test_dir = File.dirname(__FILE__) + +require 'rubygems' +require 'test/unit' +require 'multi_rails_init' +# gem 'activerecord', '>= 2.0' +require 'active_record' +require 'action_controller' +require 'action_view' +require 'active_record/fixtures' + +require plugin_test_dir + '/../init.rb' + +ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log") + +ActiveRecord::Base.configurations = YAML::load(IO.read(plugin_test_dir + "/db/database.yml")) +ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem") +ActiveRecord::Migration.verbose = false +load(File.join(plugin_test_dir, "db", "schema.rb")) + +Dir["#{plugin_test_dir}/fixtures/*.rb"].each {|file| require file } + + +class Test::Unit::TestCase #:nodoc: + self.fixture_path = File.dirname(__FILE__) + "/fixtures/" + self.use_transactional_fixtures = true + self.use_instantiated_fixtures = false + + fixtures :categories, :notes, :departments +end \ No newline at end of file diff --git a/lib/plugins/gravatar/.gitignore b/lib/plugins/gravatar/.gitignore new file mode 100644 index 000000000..4ebc8aea5 --- /dev/null +++ b/lib/plugins/gravatar/.gitignore @@ -0,0 +1 @@ +coverage diff --git a/lib/plugins/gravatar/MIT-LICENSE b/lib/plugins/gravatar/MIT-LICENSE new file mode 100644 index 000000000..6a222ac4d --- /dev/null +++ b/lib/plugins/gravatar/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2007 West Arete Computing, Inc. + +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 --git a/lib/plugins/gravatar/README.rdoc b/lib/plugins/gravatar/README.rdoc new file mode 100644 index 000000000..0b95e85e8 --- /dev/null +++ b/lib/plugins/gravatar/README.rdoc @@ -0,0 +1,55 @@ +== Gravatar Plugin + +This plugin provides a handful of view helpers for displaying gravatars +(globally-recognized avatars). + +Gravatars allow users to configure an avatar to go with their email address at +a central location: http://gravatar.com. Gravatar-aware websites (such +as yours) can then look up and display each user's preferred avatar, without +having to handle avatar management. The user gets the benefit of not having to +set up an avatar for each site that they post on. + +== Installation + + cd ~/myapp + ruby script/plugin install git://github.com/woods/gravatar-plugin.git + +or, if you're using piston[http://piston.rubyforge.org] (worth it!): + + cd ~/myapp/vendor/plugins + piston import git://github.com/woods/gravatar-plugin.git + +== Example + +If you represent your users with a model that has an +email+ method (typical +for most rails authentication setups), then you can simply use this method +in your views: + + <%= gravatar_for @user %> + +This will be replaced with the full HTML +img+ tag necessary for displaying +that user's gravatar. + +Other helpers are documented under GravatarHelper::PublicMethods. + +== Acknowledgments + +Thanks to Magnus Bergmark (http://github.com/Mange), who contributed the SSL +support in this plugin, as well as a few minor fixes. + +The following people have also written gravatar-related Ruby libraries: +* Seth Rasmussen created the gravatar gem[http://gravatar.rubyforge.org] +* Matt McCray has also created a gravatar + plugin[http://mattmccray.com/svn/rails/plugins/gravatar_helper] + +== Author + + Scott A. Woods + West Arete Computing, Inc. + http://westarete.com + scott at westarete dot com + +== TODO + +* Add specs for ssl support +* Finish rdoc documentation \ No newline at end of file diff --git a/lib/plugins/gravatar/Rakefile b/lib/plugins/gravatar/Rakefile new file mode 100644 index 000000000..e67e5e7f9 --- /dev/null +++ b/lib/plugins/gravatar/Rakefile @@ -0,0 +1,32 @@ +require 'spec/rake/spectask' +require 'rake/rdoctask' + +desc 'Default: run all specs' +task :default => :spec + +desc 'Run all application-specific specs' +Spec::Rake::SpecTask.new(:spec) do |t| + # t.rcov = true +end + +desc "Report code statistics (KLOCs, etc) from the application" +task :stats do + RAILS_ROOT = File.dirname(__FILE__) + STATS_DIRECTORIES = [ + %w(Libraries lib/), + %w(Specs spec/), + ].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) } + require 'code_statistics' + CodeStatistics.new(*STATS_DIRECTORIES).to_s +end + +namespace :doc do + desc 'Generate documentation for the assert_request plugin.' + Rake::RDocTask.new(:plugin) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'Gravatar Rails Plugin' + rdoc.options << '--line-numbers' << '--inline-source' << '--accessor' << 'cattr_accessor=rw' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') + end +end diff --git a/lib/plugins/gravatar/about.yml b/lib/plugins/gravatar/about.yml new file mode 100644 index 000000000..aa5b8b19d --- /dev/null +++ b/lib/plugins/gravatar/about.yml @@ -0,0 +1,7 @@ +author: Scott Woods, West Arete Computing +summary: View helpers for displaying gravatars. +homepage: http://github.com/woods/gravatar-plugin/ +plugin: git://github.com/woods/gravatar-plugin.git +license: MIT +version: 0.1 +rails_version: 1.0+ diff --git a/lib/plugins/gravatar/init.rb b/lib/plugins/gravatar/init.rb new file mode 100644 index 000000000..aab3f75f3 --- /dev/null +++ b/lib/plugins/gravatar/init.rb @@ -0,0 +1,2 @@ +require 'gravatar' +ActionView::Base.send :include, GravatarHelper::PublicMethods diff --git a/lib/plugins/gravatar/lib/gravatar.rb b/lib/plugins/gravatar/lib/gravatar.rb new file mode 100644 index 000000000..a0b1241b2 --- /dev/null +++ b/lib/plugins/gravatar/lib/gravatar.rb @@ -0,0 +1,88 @@ +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, :title].each { |opt| options[opt] = h(options[opt]) } + image_tag src, options + 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 --git a/lib/plugins/gravatar/spec/gravatar_spec.rb b/lib/plugins/gravatar/spec/gravatar_spec.rb new file mode 100644 index 000000000..6f78d79ad --- /dev/null +++ b/lib/plugins/gravatar/spec/gravatar_spec.rb @@ -0,0 +1,43 @@ +require 'rubygems' +require 'erb' # to get "h" +require 'active_support' # to get "returning" +require File.dirname(__FILE__) + '/../lib/gravatar' +include GravatarHelper, GravatarHelper::PublicMethods, ERB::Util + +describe "gravatar_url with a custom default URL" do + before(:each) do + @original_options = DEFAULT_OPTIONS.dup + DEFAULT_OPTIONS[:default] = "no_avatar.png" + @url = gravatar_url("somewhere") + end + + it "should include the \"default\" argument in the result" do + @url.should match(/&default=no_avatar.png/) + end + + after(:each) do + DEFAULT_OPTIONS.merge!(@original_options) + end + +end + +describe "gravatar_url with default settings" do + before(:each) do + @url = gravatar_url("somewhere") + end + + it "should have a nil default URL" do + DEFAULT_OPTIONS[:default].should be_nil + end + + it "should not include the \"default\" argument in the result" do + @url.should_not match(/&default=/) + end + +end + +describe "gravatar with a custom title option" do + it "should include the title in the result" do + gravatar('example@example.com', :title => "This is a title attribute").should match(/This is a title attribute/) + end +end diff --git a/lib/plugins/open_id_authentication/CHANGELOG b/lib/plugins/open_id_authentication/CHANGELOG new file mode 100644 index 000000000..0c8971efd --- /dev/null +++ b/lib/plugins/open_id_authentication/CHANGELOG @@ -0,0 +1,37 @@ +* Dump heavy lifting off to rack-openid gem. OpenIdAuthentication is just a simple controller concern. + +* 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 --git a/lib/plugins/open_id_authentication/README b/lib/plugins/open_id_authentication/README new file mode 100644 index 000000000..fe2b37e29 --- /dev/null +++ b/lib/plugins/open_id_authentication/README @@ -0,0 +1,223 @@ +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. + +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 %> +

    + + <%= text_field_tag "name" %> +

    + +

    + + <%= password_field_tag %> +

    + +

    + ...or use: +

    + +

    + + <%= text_field_tag "openid_identifier" %> +

    + +

    + <%= submit_tag 'Sign in', :disable_with => "Signing in…" %> +

    + <% 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 --git a/lib/plugins/open_id_authentication/Rakefile b/lib/plugins/open_id_authentication/Rakefile new file mode 100644 index 000000000..31074b856 --- /dev/null +++ b/lib/plugins/open_id_authentication/Rakefile @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the open_id_authentication plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the open_id_authentication plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'OpenIdAuthentication' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb b/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb new file mode 100644 index 000000000..6f78afc71 --- /dev/null +++ b/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb @@ -0,0 +1,11 @@ +class OpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase + def initialize(runtime_args, runtime_options = {}) + super + end + + def manifest + record do |m| + m.migration_template 'migration.rb', 'db/migrate' + end + end +end diff --git a/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb b/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb new file mode 100644 index 000000000..ef2a0cfb4 --- /dev/null +++ b/lib/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb @@ -0,0 +1,20 @@ +class <%= class_name %> < ActiveRecord::Migration + def self.up + create_table :open_id_authentication_associations, :force => true do |t| + t.integer :issued, :lifetime + t.string :handle, :assoc_type + t.binary :server_url, :secret + end + + create_table :open_id_authentication_nonces, :force => true do |t| + t.integer :timestamp, :null => false + t.string :server_url, :null => true + t.string :salt, :null => false + end + end + + def self.down + drop_table :open_id_authentication_associations + drop_table :open_id_authentication_nonces + end +end diff --git a/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb b/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb new file mode 100644 index 000000000..d13bbab23 --- /dev/null +++ b/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb @@ -0,0 +1,26 @@ +class <%= class_name %> < ActiveRecord::Migration + def self.up + drop_table :open_id_authentication_settings + drop_table :open_id_authentication_nonces + + create_table :open_id_authentication_nonces, :force => true do |t| + t.integer :timestamp, :null => false + t.string :server_url, :null => true + t.string :salt, :null => false + end + end + + def self.down + drop_table :open_id_authentication_nonces + + create_table :open_id_authentication_nonces, :force => true do |t| + t.integer :created + t.string :nonce + end + + create_table :open_id_authentication_settings, :force => true do |t| + t.string :setting + t.binary :value + end + end +end diff --git a/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb b/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb new file mode 100644 index 000000000..02fddd7fd --- /dev/null +++ b/lib/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb @@ -0,0 +1,11 @@ +class UpgradeOpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase + def initialize(runtime_args, runtime_options = {}) + super + end + + def manifest + record do |m| + m.migration_template 'migration.rb', 'db/migrate' + end + end +end diff --git a/lib/plugins/open_id_authentication/init.rb b/lib/plugins/open_id_authentication/init.rb new file mode 100644 index 000000000..84ec11fc4 --- /dev/null +++ b/lib/plugins/open_id_authentication/init.rb @@ -0,0 +1,12 @@ +if Rails.version < '3' + config.gem 'rack-openid', :lib => 'rack/openid', :version => '>=0.2.1' +end + +require 'open_id_authentication' + +config.middleware.use OpenIdAuthentication + +config.after_initialize do + OpenID::Util.logger = Rails.logger + ActionController::Base.send :include, OpenIdAuthentication +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication.rb new file mode 100644 index 000000000..48be8ddba --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication.rb @@ -0,0 +1,159 @@ +require 'uri' +require 'openid' +require 'rack/openid' + +module OpenIdAuthentication + def self.new(app) + store = OpenIdAuthentication.store + if store.nil? + Rails.logger.warn "OpenIdAuthentication.store is nil. Using in-memory store." + end + + ::Rack::OpenID.new(app, OpenIdAuthentication.store) + end + + def self.store + @@store + end + + def self.store=(*store_option) + store, *parameters = *([ store_option ].flatten) + + @@store = case store + when :memory + require 'openid/store/memory' + OpenID::Store::Memory.new + when :file + require 'openid/store/filesystem' + OpenID::Store::Filesystem.new(Rails.root.join('tmp/openids')) + when :memcache + require 'memcache' + require 'openid/store/memcache' + OpenID::Store::Memcache.new(MemCache.new(parameters)) + else + store + end + end + + self.store = nil + + 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 + + protected + # 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?(identifier = nil) #:doc: + identifier ||= open_id_identifier + !identifier.blank? || request.env[Rack::OpenID::RESPONSE] + end + + def authenticate_with_open_id(identifier = nil, options = {}, &block) #:doc: + identifier ||= open_id_identifier + + if request.env[Rack::OpenID::RESPONSE] + complete_open_id_authentication(&block) + else + begin_open_id_authentication(identifier, options, &block) + end + end + + private + def open_id_identifier + params[:openid_identifier] || params[:openid_url] + end + + def begin_open_id_authentication(identifier, options = {}) + options[:identifier] = identifier + value = Rack::OpenID.build_header(options) + response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value + head :unauthorized + end + + def complete_open_id_authentication + response = request.env[Rack::OpenID::RESPONSE] + identifier = response.display_identifier + + case response.status + when OpenID::Consumer::SUCCESS + yield Result[:successful], identifier, + OpenID::SReg::Response.from_success_response(response) + when :missing + yield Result[:missing], identifier, nil + when :invalid + yield Result[:invalid], identifier, nil + when OpenID::Consumer::CANCEL + yield Result[:canceled], identifier, nil + when OpenID::Consumer::FAILURE + yield Result[:failed], identifier, nil + when OpenID::Consumer::SETUP_NEEDED + yield Result[:setup_needed], response.setup_url, nil + end + end +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/association.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/association.rb new file mode 100644 index 000000000..8ab71bec0 --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/association.rb @@ -0,0 +1,9 @@ +module OpenIdAuthentication + class Association < ActiveRecord::Base + self.table_name = :open_id_authentication_associations + + def from_record + OpenID::Association.new(handle, secret, issued, lifetime, assoc_type) + end + end +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb new file mode 100644 index 000000000..780fb6ad2 --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb @@ -0,0 +1,55 @@ +require 'openid/store/interface' + +module OpenIdAuthentication + class DbStore < OpenID::Store::Interface + def self.cleanup_nonces + now = Time.now.to_i + Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew]) + end + + def self.cleanup_associations + now = Time.now.to_i + Association.delete_all(['issued + lifetime > ?',now]) + end + + def store_association(server_url, assoc) + remove_association(server_url, assoc.handle) + Association.create(:server_url => server_url, + :handle => assoc.handle, + :secret => assoc.secret, + :issued => assoc.issued, + :lifetime => assoc.lifetime, + :assoc_type => assoc.assoc_type) + end + + def get_association(server_url, handle = nil) + assocs = if handle.blank? + Association.find_all_by_server_url(server_url) + else + Association.find_all_by_server_url_and_handle(server_url, handle) + end + + assocs.reverse.each do |assoc| + a = assoc.from_record + if a.expires_in == 0 + assoc.destroy + else + return a + end + end if assocs.any? + + return nil + end + + def remove_association(server_url, handle) + Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0 + end + + def use_nonce(server_url, timestamp, salt) + return false if Nonce.find_by_server_url_and_timestamp_and_salt(server_url, timestamp, salt) + return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew + Nonce.create(:server_url => server_url, :timestamp => timestamp, :salt => salt) + return true + end + end +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb new file mode 100644 index 000000000..b520e4a8b --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb @@ -0,0 +1,73 @@ +require 'digest/sha1' +require 'openid/store/interface' + +module OpenIdAuthentication + class MemCacheStore < OpenID::Store::Interface + def initialize(*addresses) + @connection = ActiveSupport::Cache::MemCacheStore.new(addresses) + end + + def store_association(server_url, assoc) + server_key = association_server_key(server_url) + assoc_key = association_key(server_url, assoc.handle) + + assocs = @connection.read(server_key) || {} + assocs[assoc.issued] = assoc_key + + @connection.write(server_key, assocs) + @connection.write(assoc_key, assoc, :expires_in => assoc.lifetime) + end + + def get_association(server_url, handle = nil) + if handle + @connection.read(association_key(server_url, handle)) + else + server_key = association_server_key(server_url) + assocs = @connection.read(server_key) + return if assocs.nil? + + last_key = assocs[assocs.keys.sort.last] + @connection.read(last_key) + end + end + + def remove_association(server_url, handle) + server_key = association_server_key(server_url) + assoc_key = association_key(server_url, handle) + assocs = @connection.read(server_key) + + return false unless assocs && assocs.has_value?(assoc_key) + + assocs = assocs.delete_if { |key, value| value == assoc_key } + + @connection.write(server_key, assocs) + @connection.delete(assoc_key) + + return true + end + + def use_nonce(server_url, timestamp, salt) + return false if @connection.read(nonce_key(server_url, salt)) + return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew + @connection.write(nonce_key(server_url, salt), timestamp, :expires_in => OpenID::Nonce.skew) + return true + end + + private + def association_key(server_url, handle = nil) + "openid_association_#{digest(server_url)}_#{digest(handle)}" + end + + def association_server_key(server_url) + "openid_association_server_#{digest(server_url)}" + end + + def nonce_key(server_url, salt) + "openid_nonce_#{digest(server_url)}_#{digest(salt)}" + end + + def digest(text) + Digest::SHA1.hexdigest(text) + end + end +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb new file mode 100644 index 000000000..b28bf1679 --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb @@ -0,0 +1,5 @@ +module OpenIdAuthentication + class Nonce < ActiveRecord::Base + self.table_name = :open_id_authentication_nonces + end +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/request.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/request.rb new file mode 100644 index 000000000..e0cc8e3fc --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/request.rb @@ -0,0 +1,23 @@ +module OpenIdAuthentication + module Request + def self.included(base) + base.alias_method_chain :request_method, :openid + end + + def request_method_with_openid + if !parameters[:_method].blank? && parameters[:open_id_complete] == '1' + parameters[:_method].to_sym + else + request_method_without_openid + end + end + end +end + +# In Rails 2.3, the request object has been renamed +# from AbstractRequest to Request +if defined? ActionController::Request + ActionController::Request.send :include, OpenIdAuthentication::Request +else + ActionController::AbstractRequest.send :include, OpenIdAuthentication::Request +end diff --git a/lib/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb b/lib/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb new file mode 100644 index 000000000..cc711c9ac --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb @@ -0,0 +1,20 @@ +# http://trac.openidenabled.com/trac/ticket/156 +module OpenID + @@timeout_threshold = 20 + + def self.timeout_threshold + @@timeout_threshold + end + + def self.timeout_threshold=(value) + @@timeout_threshold = value + end + + class StandardFetcher + def make_http(uri) + http = @proxy.new(uri.host, uri.port) + http.read_timeout = http.open_timeout = OpenID.timeout_threshold + http + end + end +end \ No newline at end of file diff --git a/lib/plugins/open_id_authentication/lib/tasks/open_id_authentication_tasks.rake b/lib/plugins/open_id_authentication/lib/tasks/open_id_authentication_tasks.rake new file mode 100644 index 000000000..c71434a50 --- /dev/null +++ b/lib/plugins/open_id_authentication/lib/tasks/open_id_authentication_tasks.rake @@ -0,0 +1,30 @@ +namespace :open_id_authentication do + namespace :db do + desc "Creates authentication tables for use with OpenIdAuthentication" + task :create => :environment do + generate_migration(["open_id_authentication_tables", "add_open_id_authentication_tables"]) + end + + desc "Upgrade authentication tables from ruby-openid 1.x.x to 2.x.x" + task :upgrade => :environment do + generate_migration(["upgrade_open_id_authentication_tables", "upgrade_open_id_authentication_tables"]) + end + + def generate_migration(args) + require 'rails_generator' + require 'rails_generator/scripts/generate' + + if ActiveRecord::Base.connection.supports_migrations? + Rails::Generator::Scripts::Generate.new.run(args) + else + raise "Task unavailable to this database (no migration support)" + end + end + + desc "Clear the authentication tables" + task :clear => :environment do + OpenIdAuthentication::DbStore.cleanup_nonces + OpenIdAuthentication::DbStore.cleanup_associations + end + end +end diff --git a/lib/plugins/open_id_authentication/test/mem_cache_store_test.rb b/lib/plugins/open_id_authentication/test/mem_cache_store_test.rb new file mode 100644 index 000000000..18a943979 --- /dev/null +++ b/lib/plugins/open_id_authentication/test/mem_cache_store_test.rb @@ -0,0 +1,151 @@ +require File.dirname(__FILE__) + '/test_helper' +require File.dirname(__FILE__) + '/../lib/open_id_authentication/mem_cache_store' + +# Mock MemCacheStore with MemoryStore for testing +class OpenIdAuthentication::MemCacheStore < OpenID::Store::Interface + def initialize(*addresses) + @connection = ActiveSupport::Cache::MemoryStore.new + end +end + +class MemCacheStoreTest < Test::Unit::TestCase + ALLOWED_HANDLE = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' + + def setup + @store = OpenIdAuthentication::MemCacheStore.new + end + + def test_store + server_url = "http://www.myopenid.com/openid" + assoc = gen_assoc(0) + + # Make sure that a missing association returns no result + assert_retrieve(server_url) + + # Check that after storage, getting returns the same result + @store.store_association(server_url, assoc) + assert_retrieve(server_url, nil, assoc) + + # more than once + assert_retrieve(server_url, nil, assoc) + + # Storing more than once has no ill effect + @store.store_association(server_url, assoc) + assert_retrieve(server_url, nil, assoc) + + # Removing an association that does not exist returns not present + assert_remove(server_url, assoc.handle + 'x', false) + + # Removing an association that does not exist returns not present + assert_remove(server_url + 'x', assoc.handle, false) + + # Removing an association that is present returns present + assert_remove(server_url, assoc.handle, true) + + # but not present on subsequent calls + assert_remove(server_url, assoc.handle, false) + + # Put assoc back in the store + @store.store_association(server_url, assoc) + + # More recent and expires after assoc + assoc2 = gen_assoc(1) + @store.store_association(server_url, assoc2) + + # After storing an association with a different handle, but the + # same server_url, the handle with the later expiration is returned. + assert_retrieve(server_url, nil, assoc2) + + # We can still retrieve the older association + assert_retrieve(server_url, assoc.handle, assoc) + + # Plus we can retrieve the association with the later expiration + # explicitly + assert_retrieve(server_url, assoc2.handle, assoc2) + + # More recent, and expires earlier than assoc2 or assoc. Make sure + # that we're picking the one with the latest issued date and not + # taking into account the expiration. + assoc3 = gen_assoc(2, 100) + @store.store_association(server_url, assoc3) + + assert_retrieve(server_url, nil, assoc3) + assert_retrieve(server_url, assoc.handle, assoc) + assert_retrieve(server_url, assoc2.handle, assoc2) + assert_retrieve(server_url, assoc3.handle, assoc3) + + assert_remove(server_url, assoc2.handle, true) + + assert_retrieve(server_url, nil, assoc3) + assert_retrieve(server_url, assoc.handle, assoc) + assert_retrieve(server_url, assoc2.handle, nil) + assert_retrieve(server_url, assoc3.handle, assoc3) + + assert_remove(server_url, assoc2.handle, false) + assert_remove(server_url, assoc3.handle, true) + + assert_retrieve(server_url, nil, assoc) + assert_retrieve(server_url, assoc.handle, assoc) + assert_retrieve(server_url, assoc2.handle, nil) + assert_retrieve(server_url, assoc3.handle, nil) + + assert_remove(server_url, assoc2.handle, false) + assert_remove(server_url, assoc.handle, true) + assert_remove(server_url, assoc3.handle, false) + + assert_retrieve(server_url, nil, nil) + assert_retrieve(server_url, assoc.handle, nil) + assert_retrieve(server_url, assoc2.handle, nil) + assert_retrieve(server_url, assoc3.handle, nil) + + assert_remove(server_url, assoc2.handle, false) + assert_remove(server_url, assoc.handle, false) + assert_remove(server_url, assoc3.handle, false) + end + + def test_nonce + server_url = "http://www.myopenid.com/openid" + + [server_url, ''].each do |url| + nonce1 = OpenID::Nonce::mk_nonce + + assert_nonce(nonce1, true, url, "#{url}: nonce allowed by default") + assert_nonce(nonce1, false, url, "#{url}: nonce not allowed twice") + assert_nonce(nonce1, false, url, "#{url}: nonce not allowed third time") + + # old nonces shouldn't pass + old_nonce = OpenID::Nonce::mk_nonce(3600) + assert_nonce(old_nonce, false, url, "Old nonce #{old_nonce.inspect} passed") + end + end + + private + def gen_assoc(issued, lifetime = 600) + secret = OpenID::CryptUtil.random_string(20, nil) + handle = OpenID::CryptUtil.random_string(128, ALLOWED_HANDLE) + OpenID::Association.new(handle, secret, Time.now + issued, lifetime, 'HMAC-SHA1') + end + + def assert_retrieve(url, handle = nil, expected = nil) + assoc = @store.get_association(url, handle) + + if expected.nil? + assert_nil(assoc) + else + assert_equal(expected, assoc) + assert_equal(expected.handle, assoc.handle) + assert_equal(expected.secret, assoc.secret) + end + end + + def assert_remove(url, handle, expected) + present = @store.remove_association(url, handle) + assert_equal(expected, present) + end + + def assert_nonce(nonce, expected, server_url, msg = "") + stamp, salt = OpenID::Nonce::split_nonce(nonce) + actual = @store.use_nonce(server_url, stamp, salt) + assert_equal(expected, actual, msg) + end +end diff --git a/lib/plugins/open_id_authentication/test/normalize_test.rb b/lib/plugins/open_id_authentication/test/normalize_test.rb new file mode 100644 index 000000000..635d3abc9 --- /dev/null +++ b/lib/plugins/open_id_authentication/test/normalize_test.rb @@ -0,0 +1,32 @@ +require File.dirname(__FILE__) + '/test_helper' + +class NormalizeTest < Test::Unit::TestCase + include OpenIdAuthentication + + NORMALIZATIONS = { + "openid.aol.com/nextangler" => "http://openid.aol.com/nextangler", + "http://openid.aol.com/nextangler" => "http://openid.aol.com/nextangler", + "https://openid.aol.com/nextangler" => "https://openid.aol.com/nextangler", + "HTTP://OPENID.AOL.COM/NEXTANGLER" => "http://openid.aol.com/NEXTANGLER", + "HTTPS://OPENID.AOL.COM/NEXTANGLER" => "https://openid.aol.com/NEXTANGLER", + "loudthinking.com" => "http://loudthinking.com/", + "http://loudthinking.com" => "http://loudthinking.com/", + "http://loudthinking.com:80" => "http://loudthinking.com/", + "https://loudthinking.com:443" => "https://loudthinking.com/", + "http://loudthinking.com:8080" => "http://loudthinking.com:8080/", + "techno-weenie.net" => "http://techno-weenie.net/", + "http://techno-weenie.net" => "http://techno-weenie.net/", + "http://techno-weenie.net " => "http://techno-weenie.net/", + "=name" => "=name" + } + + def test_normalizations + NORMALIZATIONS.each do |from, to| + assert_equal to, normalize_identifier(from) + end + end + + def test_broken_open_id + assert_raises(InvalidOpenId) { normalize_identifier(nil) } + end +end diff --git a/lib/plugins/open_id_authentication/test/open_id_authentication_test.rb b/lib/plugins/open_id_authentication/test/open_id_authentication_test.rb new file mode 100644 index 000000000..ddcc17b96 --- /dev/null +++ b/lib/plugins/open_id_authentication/test/open_id_authentication_test.rb @@ -0,0 +1,46 @@ +require File.dirname(__FILE__) + '/test_helper' + +class OpenIdAuthenticationTest < Test::Unit::TestCase + def setup + @controller = Class.new do + include OpenIdAuthentication + def params() {} end + end.new + end + + def test_authentication_should_fail_when_the_identity_server_is_missing + open_id_consumer = mock() + open_id_consumer.expects(:begin).raises(OpenID::OpenIDError) + @controller.expects(:open_id_consumer).returns(open_id_consumer) + @controller.expects(:logger).returns(mock(:error => true)) + + @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| + assert result.missing? + assert_equal "Sorry, the OpenID server couldn't be found", result.message + end + end + + def test_authentication_should_be_invalid_when_the_identity_url_is_invalid + @controller.send(:authenticate_with_open_id, "!") do |result, identity_url| + assert result.invalid?, "Result expected to be invalid but was not" + assert_equal "Sorry, but this does not appear to be a valid OpenID", result.message + end + end + + def test_authentication_should_fail_when_the_identity_server_times_out + open_id_consumer = mock() + open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.") + @controller.expects(:open_id_consumer).returns(open_id_consumer) + @controller.expects(:logger).returns(mock(:error => true)) + + @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| + assert result.missing? + assert_equal "Sorry, the OpenID server couldn't be found", result.message + end + end + + def test_authentication_should_begin_when_the_identity_server_is_present + @controller.expects(:begin_open_id_authentication) + @controller.send(:authenticate_with_open_id, "http://someone.example.com") + end +end diff --git a/lib/plugins/open_id_authentication/test/status_test.rb b/lib/plugins/open_id_authentication/test/status_test.rb new file mode 100644 index 000000000..b1d5e0933 --- /dev/null +++ b/lib/plugins/open_id_authentication/test/status_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/test_helper' + +class StatusTest < Test::Unit::TestCase + include OpenIdAuthentication + + def test_state_conditional + assert Result[:missing].missing? + assert Result[:missing].unsuccessful? + assert !Result[:missing].successful? + + assert Result[:successful].successful? + assert !Result[:successful].unsuccessful? + end +end \ No newline at end of file diff --git a/lib/plugins/open_id_authentication/test/test_helper.rb b/lib/plugins/open_id_authentication/test/test_helper.rb new file mode 100644 index 000000000..43216e1ef --- /dev/null +++ b/lib/plugins/open_id_authentication/test/test_helper.rb @@ -0,0 +1,17 @@ +require 'test/unit' +require 'rubygems' + +gem 'activesupport' +require 'active_support' + +gem 'actionpack' +require 'action_controller' + +gem 'mocha' +require 'mocha' + +gem 'ruby-openid' +require 'openid' + +RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT +require File.dirname(__FILE__) + "/../lib/open_id_authentication" diff --git a/lib/plugins/rfpdf/CHANGELOG b/lib/plugins/rfpdf/CHANGELOG new file mode 100644 index 000000000..5f1081b51 --- /dev/null +++ b/lib/plugins/rfpdf/CHANGELOG @@ -0,0 +1,14 @@ +1.00 Added view template functionality +1.10 Added Chinese support +1.11 Added Japanese support +1.12 Added Korean support +1.13 Updated to fpdf.rb 1.53d. + Added makefont and fpdf_eps. + Handle \n at the beginning of a string in MultiCell. + Tried to fix clipping issue in MultiCell - still needs some work. +1.14 2006-09-26 +* Added support for @options_for_rfpdf hash for configuration: + * Added :filename option in this hash +If you're using the same settings for @options_for_rfpdf often, you might want to +put your assignment in a before_filter (perhaps overriding :filename, etc in your actions). +1.15 2009-11-20 Rails 2.* support - Thanks to Prawnto plugin for showing the way to the new TemplateHandler \ No newline at end of file diff --git a/lib/plugins/rfpdf/MIT-LICENSE b/lib/plugins/rfpdf/MIT-LICENSE new file mode 100644 index 000000000..f39a79dc0 --- /dev/null +++ b/lib/plugins/rfpdf/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2006 4ssoM LLC + +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 PURPOa AND +NONINFRINGEMENT. IN NO EVENT SaALL 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 --git a/lib/plugins/rfpdf/README b/lib/plugins/rfpdf/README new file mode 100644 index 000000000..d5a8332e5 --- /dev/null +++ b/lib/plugins/rfpdf/README @@ -0,0 +1,41 @@ +FWIW - I am migrating my apps to Prawn and Prawnto + += RFPDF Template Plugin + +A template plugin allowing the inclusion of ERB-enabled RFPDF template files. + +== +== +== TCPDF Version (The New or UTF8 Version) +== +== + +TCPDF Documentation located at: + +http://phpdocs.moodle.org/com-tecnick-tcpdf/TCPDF.html + +Example of simple use in .rhtml: + +<% + @pdf = TCPDF.new() + @pdf.SetMargins(15, 27, 15); + @pdf.AddPage(); + text_options = {:font => "freeserif"} + @pdf.draw_text(15, 10, "text", {:font_size => 12, :font => "freeserif"}) +%><%=@pdf.Output()%> + +See the following files for sample of useage: + +test_unicode.rfpdf +utf8test.txt +logo_example.png + +FPDF users can migrate to TCPDF by changing the following from: + + pdf = FPDF.new + +to: + + pdf = TCPDF.new + +ENJOY! diff --git a/lib/plugins/rfpdf/init.rb b/lib/plugins/rfpdf/init.rb new file mode 100644 index 000000000..9be784350 --- /dev/null +++ b/lib/plugins/rfpdf/init.rb @@ -0,0 +1,6 @@ +require('cgi') +require 'rfpdf' + +# Mime::Type.register "application/pdf", :pdf +# ActionView::Template::register_template_handler 'rfpdf', RFPDF::TemplateHandlers::Base + diff --git a/lib/plugins/rfpdf/lib/config/lang/eng.rb b/lib/plugins/rfpdf/lib/config/lang/eng.rb new file mode 100644 index 000000000..e05a00536 --- /dev/null +++ b/lib/plugins/rfpdf/lib/config/lang/eng.rb @@ -0,0 +1,48 @@ +#============================================================+ +# File name : eng.rb +# Begin : 2004-03-03 +# Last Update : 2005-03-19 +# +# Description : Language module for TCPDF +# (contains translated texts) +# +# +# Author: Nicola Asuni +# +# (c) Copyright: +# Tecnick.com S.r.l. +# Via Ugo Foscolo n.19 +# 09045 Quartu Sant'Elena (CA) +# ITALY +# www.tecnick.com +# info@tecnick.com +#============================================================+ + +# +# TCPDF language file (contains translated texts). +# @package com.tecnick.tcpdf +# @abstract TCPDF language file. +# @author Nicola Asuni +# @copyright 2004 Tecnick.com S.r.l (www.tecnick.com) Via Ugo Foscolo n.19 - 09045 Quartu Sant'Elena (CA) - ITALY - www.tecnick.com - info@tecnick.com +# @link http://tcpdf.sourceforge.net +# @license http://www.gnu.org/copyleft/lesser.html LGPL +# @since 2004-03-03 +# + +# ENGLISH + +@l = [] + +# PAGE META DESCRIPTORS -------------------------------------- + +@l['a_meta_charset'] = "UTF-8"; +@l['a_meta_dir'] = "ltr"; +@l['a_meta_language'] = "en"; + +# TRANSLATIONS -------------------------------------- +@l['w_page'] = "page"; + +#============================================================+ +# END OF FILE +#============================================================+ + diff --git a/lib/plugins/rfpdf/lib/core/image_science.rb b/lib/plugins/rfpdf/lib/core/image_science.rb new file mode 100644 index 000000000..8b006da8c --- /dev/null +++ b/lib/plugins/rfpdf/lib/core/image_science.rb @@ -0,0 +1,64 @@ +# 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) + out = Hash.new + out[2] = ImageScience.image_type(filename) + + image = ImageScience.with_image(filename) do |img| + out[0] = image.width + out[1] = image.height + + # 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 out[2] + when "GIF" + out['mime'] = "image/gif" + when "JPEG" + out['mime'] = "image/jpeg" + when "PNG" + out['mime'] = "image/png" + when "WBMP" + out['mime'] = "image/vnd.wap.wbmp" + when "XPM" + out['mime'] = "image/x-xpixmap" + end + out[3] = "height=\"#{image.height}\" width=\"#{image.width}\"" + + if image.colorspace == "CMYK" || image.colorspace == "RGBA" + out['channels'] = 4 + elsif image.colorspace == "RGB" + out['channels'] = 3 + end + + out['bits'] = image.depth + out['bits'] /= out['channels'] if out['channels'] + end + + out + end + +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/core/rfpdf.rb b/lib/plugins/rfpdf/lib/core/rfpdf.rb new file mode 100644 index 000000000..2c8b75273 --- /dev/null +++ b/lib/plugins/rfpdf/lib/core/rfpdf.rb @@ -0,0 +1,298 @@ +module Core::RFPDF + COLOR_PALETTE = { + :black => [0x00, 0x00, 0x00], + :white => [0xff, 0xff, 0xff], + }.freeze + + # Draw a circle at (mid_x, mid_y) with radius. + # + # Options are: + # * :border - Draw a border, 0 = no, 1 = yes? Default value is 1. + # * :border_color - Default value is COLOR_PALETTE[:black]. + # * :border_width - Default value is 0.5. + # * :fill - Fill the box, 0 = no, 1 = yes? Default value is 1. + # * :fill_color - Default value is nothing or COLOR_PALETTE[:white]. + # * :fill_colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_circle(x, y, radius, :border_color => ReportHelper::COLOR_PALETTE[:dark_blue], :border_width => 1) + # + def draw_circle(mid_x, mid_y, radius, options = {}) + options[:border] ||= 1 + options[:border_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:border_width] ||= 0.5 + options[:fill] ||= 1 + options[:fill_color] ||= Core::RFPDF::COLOR_PALETTE[:white] + options[:fill_colorspace] ||= :rgb + SetLineWidth(options[:border_width]) + set_draw_color_a(options[:border_color]) + set_fill_color_a(options[:fill_color], options[:colorspace]) + fd = "" + fd = "D" if options[:border] == 1 + fd += "F" if options[:fill] == 1 + Circle(mid_x, mid_y, radius, fd) + end + + # Draw a line from (x1, y1) to (x2, y2). + # + # Options are: + # * :line_color - Default value is COLOR_PALETTE[:black]. + # * :line_width - Default value is 0.5. + # + # Example: + # + # draw_line(x1, y1, x1, y1+h, :line_color => ReportHelper::COLOR_PALETTE[:dark_blue], :line_width => 1) + # + def draw_line(x1, y1, x2, y2, options = {}) + options[:line_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:line_width] ||= 0.5 + set_draw_color_a(options[:line_color]) + SetLineWidth(options[:line_width]) + Line(x1, y1, x2, y2) + end + + # Draw a string of text at (x, y). + # + # Options are: + # * :font_color - Default value is COLOR_PALETTE[:black]. + # * :font_size - Default value is 10. + # * :font_style - Default value is nothing or ''. + # * :colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_text(x, y, header_left, :font_size => 10) + # + def draw_text(x, y, text, options = {}) + options[:font_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:font] ||= default_font + options[:font_size] ||= 10 + options[:font_style] ||= '' + set_text_color_a(options[:font_color], options[:colorspace]) + SetFont(options[:font], options[:font_style], options[:font_size]) + SetXY(x, y) + Write(options[:font_size] + 4, text) + end + + # Draw a block of text at (x, y) bounded by left_margin and right_margin_from_right_edge. Both + # margins are measured from their corresponding edge. + # + # Options are: + # * :font_color - Default value is COLOR_PALETTE[:black]. + # * :font_size - Default value is 10. + # * :font_style - Default value is nothing or ''. + # * :colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_text_block(left_margin, 85, "question", left_margin, 280, + # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue], + # :font_size => 12, + # :font_style => 'I') + # + def draw_text_block(x, y, text, left_margin, right_margin_from_right_edge, options = {}) + options[:font] ||= default_font + options[:font_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:font_size] ||= 10 + options[:font_style] ||= '' + set_text_color_a(options[:font_color], options[:colorspace]) + SetFont(options[:font], options[:font_style], options[:font_size]) + SetXY(x, y) + SetLeftMargin(left_margin) + SetRightMargin(right_margin_from_right_edge) + Write(options[:font_size] + 4, text) + SetMargins(0,0,0) + end + + # Draw a box at (x, y), w wide and h high. + # + # Options are: + # * :border - Draw a border, 0 = no, 1 = yes? Default value is 1. + # * :border_color - Default value is COLOR_PALETTE[:black]. + # * :border_width - Default value is 0.5. + # * :fill - Fill the box, 0 = no, 1 = yes? Default value is 1. + # * :fill_color - Default value is nothing or COLOR_PALETTE[:white]. + # * :fill_colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_box(x, y - 1, 38, 22) + # + def draw_box(x, y, w, h, options = {}) + options[:border] ||= 1 + options[:border_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:border_width] ||= 0.5 + options[:fill] ||= 1 + options[:fill_color] ||= Core::RFPDF::COLOR_PALETTE[:white] + options[:fill_colorspace] ||= :rgb + SetLineWidth(options[:border_width]) + set_draw_color_a(options[:border_color]) + set_fill_color_a(options[:fill_color], options[:fill_colorspace]) + fd = "" + fd = "D" if options[:border] == 1 + fd += "F" if options[:fill] == 1 + Rect(x, y, w, h, fd) + end + + # Draw a string of text at (x, y) in a box w wide and h high. + # + # Options are: + # * :align - Vertical alignment 'C' = center, 'L' = left, 'R' = right. Default value is 'C'. + # * :border - Draw a border, 0 = no, 1 = yes? Default value is 0. + # * :border_color - Default value is COLOR_PALETTE[:black]. + # * :border_width - Default value is 0.5. + # * :fill - Fill the box, 0 = no, 1 = yes? Default value is 1. + # * :fill_color - Default value is nothing or COLOR_PALETTE[:white]. + # * :font_color - Default value is COLOR_PALETTE[:black]. + # * :font_size - Default value is nothing or 8. + # * :font_style - 'B' = bold, 'I' = italic, 'U' = underline. Default value is nothing ''. + # * :padding - Default value is nothing or 2. + # * :x_padding - Default value is nothing. + # * :valign - 'M' = middle, 'T' = top, 'B' = bottom. Default value is nothing or 'M'. + # * :colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_text_box(x, y - 1, 38, 22, + # "your_score_title", + # :fill => 0, + # :font_color => ReportHelper::COLOR_PALETTE[:blue], + # :font_line_spacing => 0, + # :font_style => "B", + # :valign => "M") + # + def draw_text_box(x, y, w, h, text, options = {}) + options[:align] ||= 'C' + options[:border] ||= 0 + options[:border_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:border_width] ||= 0.5 + options[:fill] ||= 1 + options[:fill_color] ||= Core::RFPDF::COLOR_PALETTE[:white] + options[:font] ||= default_font + options[:font_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:font_size] ||= 8 + options[:font_line_spacing] ||= options[:font_size] * 0.3 + options[:font_style] ||= '' + options[:padding] ||= 2 + options[:x_padding] ||= 0 + options[:valign] ||= "M" + if options[:fill] == 1 or options[:border] == 1 + draw_box(x, y, w, h, options) + end + SetMargins(0,0,0) + set_text_color_a(options[:font_color], options[:colorspace]) + font_size = options[:font_size] + SetFont(options[:font], options[:font_style], font_size) + font_size += options[:font_line_spacing] + case options[:valign] + when "B", "bottom" + y -= options[:padding] + when "T", "top" + y += options[:padding] + end + case options[:align] + when "L", "left" + x += options[:x_padding] + w -= options[:x_padding] + w -= options[:x_padding] + when "R", "right" + x += options[:x_padding] + w -= options[:x_padding] + w -= options[:x_padding] + end + SetXY(x, y) + if GetStringWidth(text) < w or not text["\n"].nil? and (options[:valign] == "T" || options[:valign] == "top") + text = text + "\n" + end + if GetStringWidth(text) > w or not text["\n"].nil? or (options[:valign] == "B" || options[:valign] == "bottom") + font_size += options[:font_size] * 0.1 + # TODO 2006-07-21 Level=1 - this is assuming a 2 line text + SetXY(x, y + ((h - (font_size * 2)) / 2)) if (options[:valign] == "M" || options[:valign] == "middle") + MultiCell(w, font_size, text, 0, options[:align]) + else + Cell(w, h, text, 0, 0, options[:align]) + end + end + + # Draw a string of text at (x, y) as a title. + # + # Options are: + # * :font_color - Default value is COLOR_PALETTE[:black]. + # * :font_size - Default value is 18. + # * :font_style - Default value is nothing or ''. + # * :colorspace - Default value is :rgb or ''. + # + # Example: + # + # draw_title(left_margin, 60, + # "title:", + # :font_color => ReportHelper::COLOR_PALETTE[:dark_blue]) + # + def draw_title(x, y, title, options = {}) + options[:font_color] ||= Core::RFPDF::COLOR_PALETTE[:black] + options[:font] ||= default_font + options[:font_size] ||= 18 + options[:font_style] ||= '' + set_text_color_a(options[:font_color], options[:colorspace]) + SetFont(options[:font], options[:font_style], options[:font_size]) + SetXY(x, y) + Write(options[:font_size] + 2, title) + end + + # Set the draw color. Default value is COLOR_PALETTE[:black]. + # + # Example: + # + # set_draw_color_a(ReportHelper::COLOR_PALETTE[:dark_blue]) + # + def set_draw_color_a(color = Core::RFPDF::COLOR_PALETTE[:black]) + SetDrawColor(color[0], color[1], color[2]) + end + + # Set the fill color. Default value is COLOR_PALETTE[:white]. + # + # Example: + # + # set_fill_color_a(ReportHelper::COLOR_PALETTE[:dark_blue]) + # + def set_fill_color_a(color = Core::RFPDF::COLOR_PALETTE[:white], colorspace = :rgb) + if colorspace == :cmyk + SetCmykFillColor(color[0], color[1], color[2], color[3]) + else + SetFillColor(color[0], color[1], color[2]) + end + end + + # Set the text color. Default value is COLOR_PALETTE[:white]. + # + # Example: + # + # set_text_color_a(ReportHelper::COLOR_PALETTE[:dark_blue]) + # + def set_text_color_a(color = Core::RFPDF::COLOR_PALETTE[:black], colorspace = :rgb) + if colorspace == :cmyk + SetCmykTextColor(color[0], color[1], color[2], color[3]) + else + SetTextColor(color[0], color[1], color[2]) + end + end + + # Write a string containing html characters. Default value is COLOR_PALETTE[:white]. + # + # Options are: + # * :height - Line height. Default value is 20. + # + # Example: + # + # write_html_with_options(html, :height => 12) + # + #FIXME 2007-08-07 (EJM) Level=0 - This needs to call the TCPDF version. + def write_html_with_options(html, options = {}) + options[:fill] ||= 0 + options[:height] ||= 20 + options[:new_line_after] ||= false + write_html(html, options[:new_line_after], options[:fill], options[:height]) + return + end +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/core/rmagick.rb b/lib/plugins/rfpdf/lib/core/rmagick.rb new file mode 100644 index 000000000..9311ade76 --- /dev/null +++ b/lib/plugins/rfpdf/lib/core/rmagick.rb @@ -0,0 +1,64 @@ +# 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 + + out + end + +end diff --git a/lib/plugins/rfpdf/lib/fonts/.noencode b/lib/plugins/rfpdf/lib/fonts/.noencode new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.ctg.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..e95b4f3c61c9d8f5bff699b0e8226422c2cb4565 GIT binary patch literal 8509 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Bold.z new file mode 100644 index 0000000000000000000000000000000000000000..14a2f849be97310e5ffcd9a9dde1f862dab72a61 GIT binary patch literal 263826 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%0Dsm<(B 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
  • b!4YsPU&HtX7En+)BRPl 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.ctg.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..ec0f25958afffa1598e920292015b72d8f28b269 GIT binary patch literal 7812 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-BoldOblique.z new file mode 100644 index 0000000000000000000000000000000000000000..3b5085c3b340740731697a13f71705962b2d1523 GIT binary patch literal 254774 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 + # @param string :unit User measure unit. Possible values are:
    • pt: point
    • mm: millimeter (default)
    • cm: centimeter
    • in: inch

    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).
    • 4A0
    • 2A0
    • A0
    • A1
    • A2
    • A3
    • A4 (default)
    • A5
    • A6
    • A7
    • A8
    • A9
    • A10
    • B0
    • B1
    • B2
    • B3
    • B4
    • B5
    • B6
    • B7
    • B8
    • B9
    • B10
    • C0
    • C1
    • C2
    • C3
    • C4
    • C5
    • C6
    • C7
    • C8
    • C9
    • C10
    • RA0
    • RA1
    • RA2
    • RA3
    • RA4
    • SRA0
    • SRA1
    • SRA2
    • SRA3
    • SRA4
    • LETTER
    • LEGAL
    • EXECUTIVE
    • FOLIO
    + # @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.
    • fullpage: displays the entire page on screen
    • fullwidth: uses maximum width of window
    • real: uses real size (equivalent to 100% zoom)
    • default: uses viewer default mode
    + # @param string :layout The page layout. Possible values are:
    • single: displays one page at once
    • continuous: displays pages continuously (default)
    • two: displays two pages on two columns
    • default: uses viewer default mode
    + # @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.
    + # Example:
    + #
    +	# 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();
    +	# 
    + # @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):
    • P or Portrait
    • L or Landscape
    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.
    + # 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:
    • D or empty string: draw (default)
    • F: fill
    • DF or FD: draw and fill
    + # @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]. + # Example:
    + #
    +	# :pdf->AddFont('Comic','I');
    +	# # is equivalent to:
    +	# :pdf->AddFont('Comic','I','comici.rb');
    +	# 
    + # @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):
    • empty string: regular (default)
    • B: bold
    • I: italic
    • BI or IB: bold italic
    + # @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], 'length3' => 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:
    • They are in the current directory (the one where the running script lies)
    • They are in one of the directories defined by the include_path parameter
    • They are in the directory defined by the FPDF_FONTPATH constant

    + # Example for the last case (note the trailing slash):
    + #
    +	# 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');
    +	# 

    + # 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):
    • Courier (fixed-width)
    • Helvetica or Arial (synonymous; sans serif)
    • Times (serif)
    • Symbol (symbolic)
    • ZapfDingbats (symbolic)
    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):
    • empty string: regular
    • B: bold
    • I: italic
    • U: underline
    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.
    + # 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().
    + # This method is called automatically and should not be called directly by the application.
    + # Example:
    + # The method is overriden in an inherited class in order to obtain a 3 column layout:
    + #
    +	# 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();
    +	# 
    + # @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.
    + # 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:
    • 0: no border (default)
    • 1: frame
    or a string containing some or all of the following characters (in any order):
    • L: left
    • T: top
    • R: right
    • B: bottom
    + # @param int :ln Indicates where the current position should go after the call. Possible values are:
    • 0: to the right
    • 1: to the beginning of the next line
    • 2: below
    + # 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:
    • L or empty string: left align (default value)
    • C: center
    • R: right align
    + # @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<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.
    + # 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:
    • 0: no border (default)
    • 1: frame
    or a string containing some or all of the following characters (in any order):
    • L: left
    • T: top
    • R: right
    • B: bottom
    + # @param string :align Allows to center or align the text. Possible values are:
    • L or empty string: left align
    • C: center
    • R: right align
    • J: justification (default value)
    + # @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:
    • 0: to the right
    • 1: to the beginning of the next line [DEFAULT]
    • 2: below
    + # @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.
    + # Example:
    + #
    +	# #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');
    +	# 
    + # @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 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:
    • explicit width and height (expressed in user unit)
    • one explicit dimension, the other being calculated automatically in order to keep the original proportions
    • no explicit dimension, in which case the image is put at 72 dpi
    + # Supported formats are JPEG and PNG. + # For JPEG, all flavors are allowed:
    • gray scales
    • true colors (24 bits)
    • CMYK (32 bits)
    + # For PNG, are allowed:
    • gray scales on at most 8 bits (256 levels)
    • indexed colors
    • true colors (24 bits)
    + # but are not supported:
    • Interlacing
    • Alpha channel
    + # If a transparent color is defined, it will be taken into account (but will be only interpreted by Acrobat 4 and above).
    + # The format can be specified explicitly or inferred from the file extension.
    + # It is possible to put a link on the image.
    + # Remark: if an image is used several times, only one copy will be embedded in the file.
    + # @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.
    + # 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:
    • 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.
    • D: send to the browser and force a file download with the name given by name.
    • F: save to a local file with the name given by name.
    • S: return the document as a string. name is ignored.
    If the parameter is not specified but a name is given, destination is F. If no parameter is specified at all, destination is I.
    + # @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('<>>>'; + else + l=@links[pl[4]]; + h=!@orientation_changes[l[0]].nil? ? w_pt : h_pt; + annots<>',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('<>'); + out('endobj'); + end + + # + # Adds fonts + # putfonts + # @access protected + # + def putfonts() + nf=@n; + @diffs.each do |diff| + #Encodings + newobj(); + out('<>'); + 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['length3'].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('<>'); + 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('<>'); + out('endobj'); + elsif type == 'Type0' + putType0(font) + elsif (type=='Type1' || type=='TrueType') + #Additional Type1 or TrueType font + newobj(); + 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='<>'); + 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('<>') + out('endobj') + #CIDFont + newobj() + out('<>') + 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('<>') + 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('<>'); + 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< 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 <>'; + #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< 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.
    + # 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('<>'); + out('endobj'); + + # CIDFontType2 + # A CIDFont whose glyph descriptions are based on TrueType font technology + newobj(); + out('<>'); + out('endobj'); + + # ToUnicode + # is a stream object that contains the definition of the CMap + # (PDF Reference 1.3 chap. 5.9) + newobj(); + out('<>'); + out('stream'); + out('/CIDInit /ProcSet findresource begin'); + out('12 dict begin'); + out('begincmap'); + out('/CIDSystemInfo'); + out('<> def'); + out('/CMapName /Adobe-Identity-UCS def'); + out('/CMapType 2 def'); + out('1 begincodespacerange'); + out('<0000> '); + out('endcodespacerange'); + out('1 beginbfrange'); + out('<0000> <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('<>'); + out('endobj'); + + # Font descriptor + # A font descriptor describing the CIDFont default metrics other than its glyph widths + newobj(); + 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('<>'); + open(ctgfile, "rb") do |f| + putstream(f.read()) + end + out('endobj'); + end + + # + # Converts UTF-8 strings to codepoints array.
    + # Invalid byte sequences will be replaced with 0xFFFD (replacement character)
    + # Based on: http://www.faqs.org/rfcs/rfc3629.html + #
    +	# 	  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
    +	#   ---------------------------------------------------------------------
    +	# 
    + # @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.
    + # Based on: http://www.faqs.org/rfcs/rfc2781.html + #
    +	#   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
    +	# 
    + # @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.
    + # Supports: h1, h3, 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(/ /, " "); + 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!(/ /, " "); + 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.
    + # 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:
    • 0: no border (default)
    • 1: frame
    or a string containing some or all of the following characters (in any order):
    • L: left
    • T: top
    • R: right
    • B: bottom
    + # @param int :ln Indicates where the current position should go after the call. Possible values are:
    • 0: to the right
    • 1: to the beginning of the next line
    • 2: below
    +# 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: + # + # + # + # + # + #
    + # + # 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', 'h3', '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', 'h3', '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 == 'h3' or tag == 'h3' or tag == 'h4' + margin = 1; + hrWidth = @w - @l_margin - @r_margin - margin; + if tag == 'h1' or tag == 'h3' + 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 --git a/lib/plugins/rfpdf/logo_example.png b/lib/plugins/rfpdf/logo_example.png new file mode 100644 index 0000000000000000000000000000000000000000..13799452be3cc5783f9b23e9c8341bd8fa454a50 GIT binary patch literal 19411 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

    {-sjr}eS;VA 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 to http://www.tecnick.com

    qP69p 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 bjh_r3u9p8Kd}@8|#p+-63ab4-A`1scl3L75 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.ctg.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..65a3e3d1a0dddb256d872f1d738ec97684161f4b GIT binary patch literal 7813 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 b)Rw+Z>cLuZDI@++xbJ>x?jeVV02KKjeiKW& literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans-Oblique.z new file mode 100644 index 0000000000000000000000000000000000000000..c53204e8b9ef1a4eeb04beade87cfe0c6d6d2683 GIT binary patch literal 252470 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 KYWzRV=Km@m!g4GC literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans.ctg.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..fa197554d5a57ef9310d58021aac5336e80c15de GIT binary patch literal 8517 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 H6Nvl=N5-fn literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/DejaVuSans.z b/lib/plugins/rfpdf/lib/fonts/DejaVuSans.z new file mode 100644 index 0000000000000000000000000000000000000000..79424a7892ec9f76ab8176c6650f7f0b9328c5d5 GIT binary patch literal 279448 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≦wV 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSans.ctg.z b/lib/plugins/rfpdf/lib/fonts/FreeSans.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..8b70df1c3154f87a30ae9b2491ddfd002e46826e GIT binary patch literal 4481 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 NHZPo=*FY(I{})h{#uESl literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSans.z b/lib/plugins/rfpdf/lib/fonts/FreeSans.z new file mode 100644 index 0000000000000000000000000000000000000000..b7fffac84d11d23ae57ebce505d9281c12d6cd8b GIT binary patch literal 148324 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansBold.ctg.z b/lib/plugins/rfpdf/lib/fonts/FreeSansBold.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..f8d288a0e30f2fb1d3462b369a455c4944dd5afb GIT binary patch literal 2193 zcmdte`#Tc~1Hkc5x>9rct=xP zZ9F9(T!Etg^4oY;H431nc9E8Ek~MBQe$2droF7e~R!qEFKG3Z!-<@TjF{~ggPyWMk5cw$EO9BqE??klDikw=`QCN|O|uI28#4)wgVB)_&y zd16Tk@`Q{DolnyZJk`u4rWp5Q9hu{nsZEwtX?0S1HF>By#oJSV($m<%^I)szCJ-^V z{36x+s==BkO#6*aL#6KFDnJS4K}n_atqSv7l@8MtC#EYAnDcu&lAR==Q$l>Sdr-8S zcXYSQmuzUP0phJzrv$oDVY4wuOh{6Jlaj$?pdA?Izn2mKrUa@Z`%sy$Ex=iJ;EV_` z9Z*EOpghFzw}0k${F(nLoZnI0TvS3bU#S;mYap|QX*KF(G=e=E4-Gd$eEl`N0`$EC zwb^~QYP%mKq=qqf88HE+65}>Mt2Td^nAvzy&p$+cP*E>Z)V~YTa|F_-3+c6k^aILz zj+ONpmi0Q9^=sVjF~8lXzm-(ePJu}d*3WB(3PGVpBbke!o9Y>NbFG`sF{?qNPtf}_ z?lG;~dYSE@F(F#bX)OmpVbf{};leIEB-ShxPcJTJN$KLTa76mZAUn!|UCt(&pT zS~(fpEGp zP)mN)VjwoR!rGwkSp{P2${w-ydA&XEgRRjkk)_|z9;?Gmb~7oHEw{V`-*`1%Q{O)N zykt8xQV5E;(ZfE0!2y@*iXB*>xweA$$02BRX?RGm_%*Y$6Pj%-$_h_-H`A0YZ@b^b zRqULFBH#D^srpeAD$l;pg39aHwp=1No;PCNZ~oYhCj>AUYl_xHIh*LWjZf0vKe;Du zi0XJUdV7Gv^EASB-{Jcv(!1 zE2ginAJS?xVc?E{aJnF@9kN@PP%tKmWB;XRJ!r75=OMus;0z0}&ILglUjH)p!s)YL z|GT#DTWwcKZSQn#x3^E>+D(QwFQF5|!A+-+CBz zvQT!Cq1B#~(O%@yo788HSe2_ zcE?(=(&_~-=R?0M6afU?|1FoQONcZeL;)3%Foo%=`!^z(nD8d`^TiW zW4Gckv*$2EECw(|n!SOUr*Hi}6_@H1m%%a)y-Wa}PC37dg7T|kuhSRbA}IZlMw-@&^S2S6>nw7e@7?wxaTyAO4szlC zhMgyzg+I2iHezf?ZJ|tx>9TrY-XOZMrQh&vvg6OGl@iQwaJ(^T^7{is!?JcqC1)|K zgXtuBHZxKhuNC&SuA`MDX`A5+HownweOhtaKC%2IEZ$-nGF_8FSPNBU6BJNYy+9US0FGIGFmwM&%?lvE-|sGECtPL_Q~!9FvTcVY8^XIdkWGZxCT zj0MI<5R(5~d7ZKNjz}3>^-;Yf%{6ZiuXH#grIeVgTUFy0~p!8-7 zxgRh3ey%wakwp>*pNV+fpa}c1O5C)9J8eC|R)uXmiYO)VV{F#L5owL}^XUO5eQ&oG$##CPomwudw{v9n1Uy&uw?UWGS+N@(aLRaMt z&Z6tamBf!>%1fNjtljD$+ZB_&rs}$>D7OWZi#iT8P4%~_V7CzyFCCX?n8kIWro??p v>6Y@w!9T|m1^F59P;)S4!7becoAV9hT1TS|`079X@7FDd9kp_*X48KFr%H6P literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansBold.z b/lib/plugins/rfpdf/lib/fonts/FreeSansBold.z new file mode 100644 index 0000000000000000000000000000000000000000..312eab60220f5a2eab09d49a05ee2e4c02d8435b GIT binary patch literal 46328 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 S+$AvmzwM1{i-2vR(Cf5 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.ctg.z b/lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..b843f234e37d3ce2f10dfc61822101addf4836e4 GIT binary patch literal 2039 zcmds#`8V4M0>E7ncN)_ouC&Q?Y*#a0s%QtPmiegcxJpS6j-< z3cA!YTFQ4)$#h7lTOAQcBCeqNL~WWTS!W#EKVbiY{rvFx13vGQ#+1!!PelfsK~_6O z35#rsRm@j8Qod@Dy$n*uYqI{l6JGIRy5;B1`uDBvv67t3Nq6;%`jci)aZi1E8Cu5+ zb=C`Q)Q7U}Lu;W>rYN*Q1In@itxH0gkc?uKu?CG;T{70>16K1J ztbPR+au;hngVlD#8nUp^WGqYtY8Zlg#h{KKXfy_D*@FhJK;1adWE<490`+S^NGNE$ z2x_~6hFu_(2Ex>U1{BcC2Xt-%M#F%X9bnK5=tcu3n}DV{pkEC@f&pU@pzQ(}asX&5 z0NYb&z!ZAr3Y`Fj?#e)Dnw5MtygPqSp@|!~xo=UwdN(7FuYm9dg7+;YtDzbBa)ma1 zAYflih`P!-V>a!De_%)^VwkxcJu?9c|5GvPHs+r`91F7<5es zppB-ZTPN_=-_EhtcS9bE6ahb7Y~4V zEB8@HnQ-)nQ1k8B<<_p9jymC3dMI)`?pVuSy{KXJASb?qo8TS)n=xz6x$kcaf3c#F z<6BEv3g>seW6KWodmKWgD}4JA4L^#tpH-D|dh3XS)RZ^5uWvipKgjOCHf z+SpEPp-`N@NU)+*P}msu99x{SNOYxC%h>L0(XN>8N`T59+py6ovt?qym1rlctYtf< z2q(qVE`qu2X*knDTU-HCW$rWy zt^+1RtLJfGfXq?7#OrX7*{c_LV4}=by+ZFm%IwsP=TCmlBm6y&Bn{q)u*f4K%GMCs za75t~MDA@wsQ{6KMHGXGd;n3dVEm%bC@5t7!3}hQ7v*@nwzvu2yDtRJfgzEz}{Dk8p$ObsIV1d$?x zh=D=mM?!+XkVFv@!-eEbXM(pgiR?_g>r75&6a3huI5u(dxw@0A4&IsE5Y1=Xhzo1Q zx#8l{WpR$XHj6u7lQ~~~JYTPU?Qzbv{nXu_$qUx+iPn>F>(SfR6Ikmpz?!em9Pwq2 zUt+$GVNN2Lqj=`Tb*6ghgv#VY!bW_uhG&Wj{x>6ILxW*`O<_YH!`?j$8=MR4?+hE> zS?Voa8kkt>Yg-zUEy3T=?NR}ky@w8akkUPs226PdrqU}{T9m7F0+eS1R7QNIHD9IW zpfq(*8MG@c+f}-WO0z_jiCk$bS7{=ZaHPt2>bOp6%p2wGJ4^H}d&c(maW_`;j|z~g zir(?&?ETAU>Y?j~^wIWxr=B&=QJF*qJsGLrXZ25PeZJuKB40UWJJg?k4JL=XHQZE= z*bX+PzsZtF8fix5Tc8_zSn-D~{{u}cKw9Vq+9_VtjaSeN0=8P*I-3=5>LzDsx_l|a zjTNnEt(#!cO!!-G-8h?y?mE7Trs*Kf?d~vFG(?OStK%a2{L))`@lD*4>Yb#B75g-w z_Kj!UqTrp_h~>Dn2@hVCX!nN*(KaUl_LnqT6_Hf|}$xMYD! zldsxvD^hpAUzzKorpnjcxuPsy>)tMIW$z$ScHG?q`;v_tfvUH01Nl5@`#}D|muM~= zH+>VbAixa`>n;Ge6+5>v|D)2{3c8b{xcO-4&lXQn3~o8P`$6F8tBk1gQIOPgS;%^u zrE??q*OKcxld~LM`J1Pr@n3_(1;wgd{(=whTADo^4nK&?@O>D39`%1k)_C>dmHVIV zGn(3!bG#vuZmQ3_LDBJa=xOs_LfYHTueXn!!X(m~3|69|jW@wLZK-w5XqGFNdBb~$ zIEfs3^c<<|rw^1LVsCu5J9<&CoS_f#53k>ln;($~qKiHM4nBH$-|#=}(DgitQCQ-E ktaqnOvO}Xwko(?Q8|BA^H!=hHn6FWlr=RY7bZ*`LFEPf=y#N3J literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.z b/lib/plugins/rfpdf/lib/fonts/FreeSansBoldOblique.z new file mode 100644 index 0000000000000000000000000000000000000000..f9131c338c5d9532c0ab0da0c8b904fab371d534 GIT binary patch literal 45965 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansOblique.ctg.z b/lib/plugins/rfpdf/lib/fonts/FreeSansOblique.ctg.z new file mode 100644 index 0000000000000000000000000000000000000000..35f90ff207e22a2ec7d0bc6465052fae8696fc52 GIT binary patch literal 2317 zcmdtd`#;l-0>E)|o0&^f5uPqcS~fKqxmB(;3yn!_4T=6c zc2nwP2Aw`K^Qq{;*O|9E9N&EfV_70*v(-wA17;qbeuVHHnZ@JwZh4>bT; zjZCcIyk{=U4qF7+P!NF?)lST5nKvQ8o`R%Ru^vsOiPx5aDt5&H-IjxSqe{}2%PJ4DYn^ANiz<*^vOMRbLUl>jN-~|cDb@wgBpT985!|qSLUOrQrX{sEH5cNDLd`^@@eDOM9;@N!PpQiHtY!QmW%$qP>xLyDbhfU1hsBBCDVGdOtxIies;KuPK>bw#tL*CH0nlAXBIJ*$MnP^uNO*01h~Y0m_~8%u>F z+2p#~yq-CNmp#>%T^m;S6yKvH_(W5YY<6NDN8YnMc-WF^L#qv}t9I_09`rs%wWqOZ zb!<`3!l0Ks)lOAQd@fGvjUDYLrv6Y!LsKbns`4~p@j@TS?KpVm?A9`$#0N%wFt?B+ zGZ(j(MVvr9>}E)h%0d$hg8IzeLZfD49+h8CEV|OP)HohBG7ugcU+N%hYxHF) z9f=(Kgi4OAx6!{(=|<#QCX~m@Ivf4!mChp^_k^mivXRCki^_u|T=0C!HrdM*-+M|_ z@#cG^gWqr&3V@mfl?)Lfe^tsx_h?do7J(kCgb-vBt`;C_Vmb>)r`S&;wqC|)P z!t~V*!aiuMRkP!viktj*rmz1Z9Dv5b5M_S+zfIf92u>NXD8%D7e!uCP34%vP90XBn z%YW5USo|u7;E0Wdrw`}f{vSTgM#7P~l_IA+xhx_@a@HKlB#RJvz5IwI$vIafYf9vi z*Eg5^=3~7k{+)irIr|BkneaS*IN&74o?OYkn=6dRkM23?S3}BW-w6{^@gvlefi+|y zJF8cif*-Ru=@U)LWYf{Y3-V#YNo@2Kkt-DPMDnh|Q{Xspc_P0{-quKP`5f!%5tot@ zus3){1y8Hxeiy7cztA1rVHx8S^Tbf_!TB%$!QGa$$e7wpf!eus*Wk{=n9!J~fr1(5 zmlp;Rv&#ZnR;Mu8dCaum`xGgIMn?+CqG5c0z$tPKEt4%w6pcFf`wx){X&E#jO*E3! zA2dW3)9$H+X`(TselK^@E!FL{b ztle*++7G}Hor3RvJ^$=M(H2Qt5^!yKVy*S<)%EYYnz8=^Pnx91IjpbzY8{MORRQap z9NM{Ezpd%B-rMb3c{!^1dT7o4Q^?wvyUoSesg0pxrxxdp*4AY$uPcA{ns0#pKatiq zBserl#vL1vIS3>Z{Kl9TxAHS>%qQsiZ;|D3OHcVJ0WbI+bT6ia6HSF7`N zh*shKn*l!}DttKik}VM)K9~!TiLT+JVV5=&ZNmq`fG{FDe5CghnuzSK9pq%yd{#Cr x7o}(gQ$ATF7iAJRb_=SbrwhcUoXY4ag4mhEj$RaW1^W8>&aW%aw92f9{tek}86p4x literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/FreeSansOblique.z b/lib/plugins/rfpdf/lib/fonts/FreeSansOblique.z new file mode 100644 index 0000000000000000000000000000000000000000..c55489e22b01331ee51aebf4b9352e4ea2b31f40 GIT binary patch literal 55670 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%0D~3 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ðL~EikD&iDs3Y(uLWqY@4xvEg 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 = added in DejaVu fonts + +U+0020 space original +U+0021 exclam original +U+0022 quotedbl original +U+0023 numbersign original +U+0024 dollar original +U+0025 percent original +U+0026 ampersand original +U+0027 quotesingle original +U+0028 parenleft original +U+0029 parenright original +U+002a asterisk original +U+002b plus original +U+002c comma original +U+002d hyphen original +U+002e period original +U+002f slash original +U+0030 zero original +U+0031 one original +U+0032 two original +U+0033 three original +U+0034 four original +U+0035 five original +U+0036 six original +U+0037 seven original +U+0038 eight original +U+0039 nine original +U+003a colon original +U+003b semicolon original +U+003c less original +U+003d equal original +U+003e greater original +U+003f question original +U+0040 at original +U+0041 A original +U+0042 B original +U+0043 C original +U+0044 D original +U+0045 E original +U+0046 F original +U+0047 G original +U+0048 H original +U+0049 I original +U+004a J original +U+004b K original +U+004c L original +U+004d M original +U+004e N original +U+004f O original +U+0050 P original +U+0051 Q original +U+0052 R original +U+0053 S original +U+0054 T original +U+0055 U original +U+0056 V original +U+0057 W original +U+0058 X original +U+0059 Y original +U+005a Z original +U+005b bracketleft original +U+005c backslash original +U+005d bracketright original +U+005e asciicircum original +U+005f underscore original +U+0060 grave original +U+0061 a original +U+0062 b original +U+0063 c original +U+0064 d original +U+0065 e original +U+0066 f original +U+0067 g original +U+0068 h original +U+0069 i original +U+006a j original +U+006b k original +U+006c l original +U+006d m original +U+006e n original +U+006f o original +U+0070 p original +U+0071 q original +U+0072 r original +U+0073 s original +U+0074 t original +U+0075 u original +U+0076 v original +U+0077 w original +U+0078 x original +U+0079 y original +U+007a z original +U+007b braceleft original +U+007c bar original +U+007d braceright original +U+007e asciitilde original +U+00a0 nonbreakingspace original +U+00a1 exclamdown original +U+00a2 cent original +U+00a3 sterling original +U+00a4 currency original +U+00a5 yen original +U+00a6 brokenbar original +U+00a7 section original +U+00a8 dieresis original +U+00a9 copyright original +U+00aa ordfeminine original +U+00ab guillemotleft original +U+00ac logicalnot original +U+00ad sfthyphen original +U+00ae registered original +U+00af macron original +U+00b0 degree original +U+00b1 plusminus original +U+00b2 twosuperior original +U+00b3 threesuperior original +U+00b4 acute original +U+00b5 mu original +U+00b6 paragraph original +U+00b7 periodcentered original +U+00b8 cedilla original +U+00b9 onesuperior original +U+00ba ordmasculine original +U+00bb guillemotright original +U+00bc onequarter original +U+00bd onehalf original +U+00be threequarters original +U+00bf questiondown original +U+00c0 Agrave original +U+00c1 Aacute original +U+00c2 Acircumflex original +U+00c3 Atilde original +U+00c4 Adieresis original +U+00c5 Aring original +U+00c6 AE original +U+00c7 Ccedilla original +U+00c8 Egrave original +U+00c9 Eacute original +U+00ca Ecircumflex original +U+00cb Edieresis original +U+00cc Igrave original +U+00cd Iacute original +U+00ce Icircumflex original +U+00cf Idieresis original +U+00d0 Eth original +U+00d1 Ntilde original +U+00d2 Ograve original +U+00d3 Oacute original +U+00d4 Ocircumflex original +U+00d5 Otilde original +U+00d6 Odieresis original +U+00d7 multiply original +U+00d8 Oslash original +U+00d9 Ugrave original +U+00da Uacute original +U+00db Ucircumflex original +U+00dc Udieresis original +U+00dd Yacute original +U+00de Thorn original +U+00df germandbls original +U+00e0 agrave original +U+00e1 aacute original +U+00e2 acircumflex original +U+00e3 atilde original +U+00e4 adieresis original +U+00e5 aring original +U+00e6 ae original +U+00e7 ccedilla original +U+00e8 egrave original +U+00e9 eacute original +U+00ea ecircumflex original +U+00eb edieresis original +U+00ec igrave original +U+00ed iacute original +U+00ee icircumflex original +U+00ef idieresis original +U+00f0 eth original +U+00f1 ntilde original +U+00f2 ograve original +U+00f3 oacute original +U+00f4 ocircumflex original +U+00f5 otilde original +U+00f6 odieresis original +U+00f7 divide original +U+00f8 oslash original +U+00f9 ugrave original +U+00fa uacute original +U+00fb ucircumflex original +U+00fc udieresis original +U+00fd yacute original +U+00fe thorn original +U+00ff ydieresis original +U+0100 Amacron 1.5 +U+0101 amacron 1.5 +U+0102 Abreve 1.5 +U+0103 abreve 1.5 +U+0104 Aogonek 1.4 +U+0105 aogonek 1.4 +U+0106 Cacute original +U+0107 cacute original +U+0108 Ccircumflex 1.5 +U+0109 ccircumflex 1.5 +U+010a Cdotaccent 1.5 +U+010b cdotaccent 1.5 +U+010c Ccaron original +U+010d ccaron original +U+010e Dcaron 1.0 +U+010f dcaron 1.0 +U+0110 Dcroat 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0111 dcroat original +U+0112 Emacron 1.5 +U+0113 emacron 1.5 +U+0114 Ebreve 1.5 +U+0115 ebreve 1.5 +U+0116 Edotaccent 1.5 +U+0117 edotaccent 1.5 +U+0118 Eogonek 1.4 +U+0119 eogonek 1.4 +U+011a Ecaron 1.0 +U+011b ecaron 1.0 +U+011c Gcircumflex 1.5 +U+011d gcircumflex 1.5 +U+011e Gbreve original +U+011f gbreve original +U+0120 Gdotaccent 1.5 +U+0121 gdotaccent 1.5 +U+0122 Gcommaaccent 1.11 +U+0123 gcommaaccent 1.11 +U+0124 Hcircumflex 1.5 +U+0125 hcircumflex 1.5 +U+0126 Hbar 1.12 +U+0127 hbar 1.12 +U+0128 Itilde 1.5 +U+0129 itilde 1.5 +U+012a Imacron 1.5 +U+012b imacron 1.5 +U+012c Ibreve 1.5 +U+012d ibreve 1.5 +U+012e Iogonek 1.11 +U+012f iogonek 1.11 +U+0130 Idotaccent original +U+0131 dotlessi original +U+0132 IJ 1.11 +U+0133 ij 1.11 +U+0134 Jcircumflex 1.5 +U+0135 jcircumflex 1.5 +U+0136 Kcommaaccent 1.11 +U+0137 kcommaaccent 1.11 +U+0138 kgreenlandic 1.12 +U+0139 Lacute 1.1 +U+013a lacute 1.1 +U+013b Lcommaaccent 1.11 +U+013c lcommaaccent 1.11 +U+013d Lcaron 1.1 +U+013e lcaron 1.1 +U+013f Ldot 1.2 +U+0140 ldot 1.2 +U+0141 Lslash original +U+0142 lslash original +U+0143 Nacute 1.4 +U+0144 nacute 1.4 +U+0145 Ncommaaccent 1.11 +U+0146 ncommaaccent 1.11 +U+0147 Ncaron 1.0 +U+0148 ncaron 1.0 +U+0149 napostrophe 1.12 +U+014a Eng 1.12 +U+014b eng 1.12 +U+014c Omacron 1.5 +U+014d omacron 1.5 +U+014e Obreve 1.5 +U+014f obreve 1.5 +U+0150 Ohungarumlaut 1.5 +U+0151 ohungarumlaut 1.5 +U+0152 OE original +U+0153 oe original +U+0154 Racute 1.1 +U+0155 racute 1.1 +U+0156 Rcommaaccent 1.11 +U+0157 rcommaaccent 1.11 +U+0158 Rcaron 1.0 +U+0159 rcaron 1.0 +U+015a Sacute 1.4 +U+015b sacute 1.4 +U+015c Scircumflex 1.5 +U+015d scircumflex 1.5 +U+015e Scedilla original +U+015f scedilla original +U+0160 Scaron original +U+0161 scaron original +U+0162 Tcommaaccent 1.5 +U+0163 tcommaaccent 1.5 +U+0164 Tcaron 1.0 +U+0165 tcaron 1.0 +U+0166 Tbar 1.12 +U+0167 tbar 1.12 +U+0168 Utilde 1.5 +U+0169 utilde 1.5 +U+016a Umacron 1.5 +U+016b umacron 1.5 +U+016c Ubreve 1.5 +U+016d ubreve 1.5 +U+016e Uring 1.0 +U+016f uring 1.0 +U+0170 Uhungarumlaut 1.5 +U+0171 uhungarumlaut 1.5 +U+0172 Uogonek 1.11 +U+0173 uogonek 1.11 +U+0174 Wcircumflex 1.2 +U+0175 wcircumflex 1.2 +U+0176 Ycircumflex 1.2 +U+0177 ycircumflex 1.2 +U+0178 Ydieresis original +U+0179 Zacute 1.4 +U+017a zacute 1.4 +U+017b Zdotaccent 1.4 +U+017c zdotaccent 1.4 +U+017d Zcaron original +U+017e zcaron original +U+017f longs 1.12 +U+0180 uni0180 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.12 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0181 uni0181 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0182 uni0182 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0183 uni0183 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0184 uni0184 2.3 +U+0185 uni0185 2.3 +U+0186 uni0186 1.15 +U+0187 uni0187 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0188 uni0188 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0189 uni0189 2.1 +U+018a uni018A 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+018b uni018B 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+018c uni018C 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+018d uni018D 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+018e uni018E 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+018f uni018F 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0190 uni0190 1.15 +U+0191 uni0191 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0192 florin original +U+0193 uni0193 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0194 uni0194 1.14 +U+0195 uni0195 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.6 (Sans ExtraLight) +U+0196 uni0196 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0197 uni0197 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0198 uni0198 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+0199 uni0199 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+019a uni019A 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+019b uni019B 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+019c uni019C 2.3 +U+019d uni019D 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+019e uni019E 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+019f uni019F 2.3 +U+01a0 Ohorn 2.3 +U+01a1 ohorn 2.3 +U+01a2 uni01A2 2.3 +U+01a3 uni01A3 2.3 +U+01a4 uni01A4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01a5 uni01A5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01a6 uni01A6 2.3 +U+01a7 uni01A7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01a8 uni01A8 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01a9 uni01A9 2.2 +U+01aa uni01AA 2.3 +U+01ab uni01AB 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01ac uni01AC 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01ad uni01AD 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01ae uni01AE 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01af Uhorn 2.3 +U+01b0 uhorn 2.3 +U+01b1 uni01B1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01b2 uni01B2 2.3 +U+01b3 uni01B3 2.3 +U+01b4 uni01B4 2.3 +U+01b5 uni01B5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01b6 uni01B6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01b7 uni01B7 2.3 +U+01b8 uni01B8 2.3 +U+01b9 uni01B9 2.3 +U+01ba uni01BA 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+01bb uni01BB 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01bc uni01BC 2.3 +U+01bd uni01BD 2.3 +U+01be uni01BE 2.3 +U+01bf uni01BF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+01c0 uni01C0 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01c1 uni01C1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01c2 uni01C2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+01c3 uni01C3 2.2 +U+01c4 uni01C4 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01c5 uni01C5 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01c6 uni01C6 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01c7 uni01C7 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01c8 uni01C8 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01c9 uni01C9 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01ca uni01CA 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01cb uni01CB 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01cc uni01CC 1.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01cd uni01CD 1.15 +U+01ce uni01CE 1.15 +U+01cf uni01CF 1.15 +U+01d0 uni01D0 1.15 +U+01d1 uni01D1 1.15 +U+01d2 uni01D2 1.15 +U+01d3 uni01D3 1.15 +U+01d4 uni01D4 1.15 +U+01d5 uni01D5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01d6 uni01D6 1.13 +U+01d7 uni01D7 2.3 +U+01d8 uni01D8 2.3 +U+01d9 uni01D9 2.3 +U+01da uni01DA 2.3 +U+01db uni01DB 2.3 +U+01dc uni01DC 2.3 +U+01dd uni01DD 2.2 +U+01de uni01DE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01df uni01DF 1.13 +U+01e0 uni01E0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01e1 uni01E1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01e2 uni01E2 1.5 +U+01e3 uni01E3 1.5 +U+01e4 uni01E4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01e5 uni01E5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01e6 Gcaron 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01e7 gcaron 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01e8 uni01E8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01e9 uni01E9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01ea uni01EA 1.9 +U+01eb uni01EB 1.9 +U+01ec uni01EC 1.9 +U+01ed uni01ED 1.9 +U+01ee uni01EE 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01ef uni01EF 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01f0 uni01F0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono) +U+01f1 uni01F1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01f2 uni01F2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01f3 uni01F3 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01f4 uni01F4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01f5 uni01F5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01f6 uni01F6 2.3 +U+01f7 uni01F7 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+01f8 uni01F8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01f9 uni01F9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01fa Aringacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01fb aringacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+01fc AEacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01fd aeacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01fe Oslashacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+01ff oslashacute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0200 uni0200 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0201 uni0201 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0202 uni0202 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0203 uni0203 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0204 uni0204 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0205 uni0205 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0206 uni0206 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0207 uni0207 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0208 uni0208 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0209 uni0209 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020a uni020A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020b uni020B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020c uni020C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020d uni020D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020e uni020E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+020f uni020F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0210 uni0210 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0211 uni0211 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0212 uni0212 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0213 uni0213 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0214 uni0214 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0215 uni0215 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0216 uni0216 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0217 uni0217 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0218 Scommaaccent 1.5 +U+0219 scommaaccent 1.5 +U+021a uni021A 1.5 +U+021b uni021B 1.5 +U+021c uni021C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+021d uni021D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+021e uni021E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+021f uni021F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0220 uni0220 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0221 uni0221 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0222 uni0222 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0223 uni0223 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0224 uni0224 2.3 +U+0225 uni0225 2.3 +U+0226 uni0226 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0227 uni0227 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0228 uni0228 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0229 uni0229 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+022a uni022A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+022b uni022B 1.13 +U+022c uni022C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+022d uni022D 1.13 +U+022e uni022E 1.10 +U+022f uni022F 1.10 +U+0230 uni0230 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+0231 uni0231 1.13 +U+0232 uni0232 1.5 +U+0233 uni0233 1.5 +U+0234 uni0234 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0235 uni0235 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0236 uni0236 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0237 dotlessj 1.5 +U+0238 uni0238 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+0239 uni0239 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+023a uni023A 2.3 +U+023b uni023B 2.3 +U+023c uni023C 2.3 +U+023d uni023D 2.3 +U+023e uni023E 2.3 +U+023f uni023F 2.3 +U+0240 uni0240 2.3 +U+0241 uni0241 2.3 +U+0242 uni0242 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+0243 uni0243 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0244 uni0244 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0245 uni0245 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0246 uni0246 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0247 uni0247 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0248 uni0248 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0249 uni0249 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+024a uni024A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+024b uni024B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+024c uni024C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+024d uni024D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+024e uni024E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+024f uni024F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0250 uni0250 1.14 +U+0251 uni0251 1.14 +U+0252 uni0252 1.14 +U+0253 uni0253 1.14 +U+0254 uni0254 1.14 +U+0255 uni0255 1.14 +U+0256 uni0256 1.14 +U+0257 uni0257 1.14 +U+0258 uni0258 1.14 +U+0259 uni0259 1.14 +U+025a uni025A 1.14 +U+025b uni025B 1.14 +U+025c uni025C 1.14 +U+025d uni025D 1.14 +U+025e uni025E 1.14 +U+025f uni025F 1.14 +U+0260 uni0260 1.14 +U+0261 uni0261 1.14 +U+0262 uni0262 1.14 +U+0263 uni0263 1.14 +U+0264 uni0264 1.14 +U+0265 uni0265 1.14 +U+0266 uni0266 1.14 +U+0267 uni0267 1.14 +U+0268 uni0268 1.14 +U+0269 uni0269 1.14 +U+026a uni026A 1.14 +U+026b uni026B 1.14 +U+026c uni026C 1.14 +U+026d uni026D 1.14 +U+026e uni026E 1.14 +U+026f uni026F 1.14 +U+0270 uni0270 1.14 +U+0271 uni0271 1.14 +U+0272 uni0272 1.14 +U+0273 uni0273 1.14 +U+0274 uni0274 1.14 +U+0275 uni0275 1.14 +U+0276 uni0276 1.14 +U+0277 uni0277 1.14 +U+0278 uni0278 1.14 +U+0279 uni0279 1.14 +U+027a uni027A 1.14 +U+027b uni027B 1.14 +U+027c uni027C 1.14 +U+027d uni027D 1.14 +U+027e uni027E 1.14 +U+027f uni027F 1.14 +U+0280 uni0280 1.14 +U+0281 uni0281 1.14 +U+0282 uni0282 1.14 +U+0283 uni0283 1.14 +U+0284 uni0284 1.14 +U+0285 uni0285 1.14 +U+0286 uni0286 1.14 +U+0287 uni0287 1.14 +U+0288 uni0288 1.14 +U+0289 uni0289 1.14 +U+028a uni028A 1.14 +U+028b uni028B 1.14 +U+028c uni028C 1.14 +U+028d uni028D 1.14 +U+028e uni028E 1.14 +U+028f uni028F 1.14 +U+0290 uni0290 1.14 +U+0291 uni0291 1.14 +U+0292 uni0292 1.14 +U+0293 uni0293 1.14 +U+0294 uni0294 1.14 +U+0295 uni0295 1.14 +U+0296 uni0296 1.14 +U+0297 uni0297 1.14 +U+0298 uni0298 1.14 +U+0299 uni0299 1.14 +U+029a uni029A 1.14 +U+029b uni029B 1.14 +U+029c uni029C 1.14 +U+029d uni029D 1.14 +U+029e uni029E 1.14 +U+029f uni029F 1.14 +U+02a0 uni02A0 1.14 +U+02a1 uni02A1 1.14 +U+02a2 uni02A2 1.14 +U+02a3 uni02A3 1.14 +U+02a4 uni02A4 1.14 +U+02a5 uni02A5 1.14 +U+02a6 uni02A6 1.14 +U+02a7 uni02A7 1.14 +U+02a8 uni02A8 1.14 +U+02a9 uni02A9 1.14 +U+02aa uni02AA 1.14 +U+02ab uni02AB 1.14 +U+02ac uni02AC 1.14 +U+02ad uni02AD 1.14 +U+02ae uni02AE 1.14 +U+02af uni02AF 1.14 +U+02b0 uni02B0 1.14 +U+02b1 uni02B1 1.14 +U+02b2 uni02B2 1.14 +U+02b3 uni02B3 1.14 +U+02b4 uni02B4 1.14 +U+02b5 uni02B5 1.14 +U+02b6 uni02B6 1.14 +U+02b7 uni02B7 1.14 +U+02b8 uni02B8 1.14 +U+02b9 uni02B9 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+02ba uni02BA 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02bb uni02BB 1.5 +U+02bc afii57929 1.12 +U+02bd afii64937 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+02be uni02BE 2.2 +U+02bf uni02BF 2.2 +U+02c0 uni02C0 1.14 +U+02c1 uni02C1 1.14 +U+02c2 uni02C2 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02c3 uni02C3 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02c4 uni02C4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02c5 uni02C5 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02c6 circumflex original +U+02c7 caron original +U+02c8 uni02C8 2.0 +U+02c9 uni02C9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+02ca uni02CA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+02cb uni02CB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+02cc uni02CC 2.0 +U+02cd uni02CD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+02ce uni02CE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+02cf uni02CF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+02d0 uni02D0 1.14 +U+02d1 uni02D1 1.14 +U+02d2 uni02D2 2.0 +U+02d3 uni02D3 2.2 +U+02d4 uni02D4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02d5 uni02D5 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02d6 uni02D6 2.0 +U+02d7 uni02D7 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02d8 breve original +U+02d9 dotaccent original +U+02da ring original +U+02db ogonek original +U+02dc tilde original +U+02dd hungarumlaut original +U+02de uni02DE 2.0 +U+02df uni02DF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02e0 uni02E0 1.14 +U+02e1 uni02E1 1.14 +U+02e2 uni02E2 1.14 +U+02e3 uni02E3 1.14 +U+02e4 uni02E4 1.14 +U+02e5 uni02E5 2.0 +U+02e6 uni02E6 2.0 +U+02e7 uni02E7 2.0 +U+02e8 uni02E8 2.0 +U+02e9 uni02E9 2.0 +U+02ec uni02EC 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02ed uni02ED 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+02ee uni02EE 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+02f3 uni02F3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+02f7 uni02F7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+0300 gravecomb 1.15 +U+0301 acutecomb 1.15 +U+0302 uni0302 1.15 +U+0303 tildecomb 1.15 +U+0304 uni0304 1.15 +U+0305 uni0305 2.0 +U+0306 uni0306 1.15 +U+0307 uni0307 1.15 +U+0308 uni0308 1.15 +U+0309 hookabovecomb 2.1 +U+030a uni030A 1.15 +U+030b uni030B 1.15 +U+030c uni030C 1.15 +U+030d uni030D 2.0 +U+030e uni030E 2.0 +U+030f uni030F 2.0 +U+0310 uni0310 2.0 +U+0311 uni0311 2.0 +U+0312 uni0312 1.11 +U+0313 uni0313 2.1 +U+0314 uni0314 2.1 +U+0315 uni0315 2.0 +U+0316 uni0316 2.0 +U+0317 uni0317 2.0 +U+0318 uni0318 2.0 +U+0319 uni0319 2.0 +U+031a uni031A 2.1 +U+031b uni031B 2.1 +U+031c uni031C 2.0 +U+031d uni031D 2.0 +U+031e uni031E 2.0 +U+031f uni031F 2.0 +U+0320 uni0320 2.0 +U+0321 uni0321 1.15 +U+0322 uni0322 1.15 +U+0323 dotbelowcomb 2.1 +U+0324 uni0324 2.0 +U+0325 uni0325 2.0 +U+0326 uni0326 1.5 +U+0327 uni0327 2.1 +U+0328 uni0328 2.1 +U+0329 uni0329 2.0 +U+032a uni032A 2.0 +U+032b uni032B 2.1 +U+032c uni032C 2.0 +U+032d uni032D 2.0 +U+032e uni032E 2.0 +U+032f uni032F 2.0 +U+0330 uni0330 2.0 +U+0331 uni0331 2.0 +U+0332 uni0332 2.0 +U+0333 uni0333 2.1 +U+0334 uni0334 2.3 +U+0335 uni0335 2.3 +U+0336 uni0336 2.3 +U+0337 uni0337 2.3 +U+0338 uni0338 2.3 +U+0339 uni0339 2.0 +U+033a uni033A 2.0 +U+033b uni033B 2.0 +U+033c uni033C 2.1 +U+033d uni033D 2.0 +U+033e uni033E 2.1 +U+033f uni033F 2.1 +U+0340 uni0340 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0341 uni0341 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0342 uni0342 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0343 uni0343 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0344 uni0344 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0345 uni0345 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0346 uni0346 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0347 uni0347 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0348 uni0348 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0349 uni0349 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034a uni034A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034b uni034B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034c uni034C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034d uni034D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034e uni034E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+034f uni034F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0351 uni0351 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0352 uni0352 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique) +U+0353 uni0353 2.5 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0357 uni0357 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0358 uni0358 2.3 +U+035c uni035C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+035d uni035D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+035e uni035E 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+035f uni035F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0360 uni0360 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0361 uni0361 2.0 +U+0362 uni0362 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0374 uni0374 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0375 uni0375 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+037a uni037A 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+037b uni037B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+037c uni037C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+037d uni037D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+037e uni037E 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0384 tonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0385 dieresistonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0386 Alphatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0387 anoteleia 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0388 Epsilontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0389 Etatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+038a Iotatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+038c Omicrontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+038e Upsilontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+038f Omegatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+0390 iotadieresistonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0391 Alpha 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0392 Beta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0393 Gamma 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0394 uni0394 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0395 Epsilon 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0396 Zeta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0397 Eta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0398 Theta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+0399 Iota 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039a Kappa 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039b Lambda 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039c Mu 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039d Nu 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039e Xi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+039f Omicron 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a0 Pi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a1 Rho 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a3 Sigma 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a4 Tau 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a5 Upsilon 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a6 Phi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03a7 Chi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03a8 Psi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03a9 Omega original +U+03aa Iotadieresis 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03ab Upsilondieresis 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.1 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03ac alphatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03ad epsilontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03ae etatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03af iotatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b0 upsilondieresistonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b1 alpha 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b2 beta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b3 gamma 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b4 delta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b5 epsilon 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03b6 zeta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b7 eta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03b8 theta 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03b9 iota 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03ba kappa 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03bb lambda 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03bc uni03BC 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03bd nu 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03be xi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03bf omicron 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03c0 pi original +U+03c1 rho 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c2 sigma1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c3 sigma 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c4 tau 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c5 upsilon 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c6 phi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c7 chi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c8 psi 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03c9 omega 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03ca iotadieresis 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03cb upsilondieresis 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03cc omicrontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03cd upsilontonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03ce omegatonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+03d0 uni03D0 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d1 theta1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d2 Upsilon1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d3 uni03D3 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d4 uni03D4 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d5 phi1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d6 omega1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d7 uni03D7 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d8 uni03D8 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03d9 uni03D9 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03da uni03DA 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03db uni03DB 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03dc uni03DC 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03dd uni03DD 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03de uni03DE 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03df uni03DF 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03e0 uni03E0 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03e1 uni03E1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03e2 uni03E2 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e3 uni03E3 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e4 uni03E4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e5 uni03E5 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e6 uni03E6 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e7 uni03E7 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e8 uni03E8 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03e9 uni03E9 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03ea uni03EA 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03eb uni03EB 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03ec uni03EC 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03ed uni03ED 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03ee uni03EE 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03ef uni03EF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+03f0 uni03F0 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03f1 uni03F1 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03f2 uni03F2 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f3 uni03F3 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f4 uni03F4 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f5 uni03F5 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f6 uni03F6 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f7 uni03F7 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f8 uni03F8 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03f9 uni03F9 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03fa uni03FA 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03fb uni03FB 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03fc uni03FC 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+03fd uni03FD 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03fe uni03FE 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+03ff uni03FF 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.0 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+0400 uni0400 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0401 afii10023 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0402 afii10051 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0403 afii10052 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0404 afii10053 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0405 afii10054 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0406 afii10055 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0407 afii10056 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0408 afii10057 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0409 afii10058 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+040a afii10059 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+040b afii10060 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+040c afii10061 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+040d uni040D 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+040e afii10062 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+040f afii10145 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0410 afii10017 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0411 afii10018 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0412 afii10019 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0413 afii10020 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0414 afii10021 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0415 afii10022 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0416 afii10024 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0417 afii10025 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0418 afii10026 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0419 afii10027 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+041a afii10028 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+041b afii10029 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+041c afii10030 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+041d afii10031 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+041e afii10032 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+041f afii10033 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0420 afii10034 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0421 afii10035 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0422 afii10036 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0423 afii10037 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0424 afii10038 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0425 afii10039 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0426 afii10040 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0427 afii10041 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0428 afii10042 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0429 afii10043 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+042a afii10044 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+042b afii10045 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+042c afii10046 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+042d afii10047 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+042e afii10048 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+042f afii10049 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0430 afii10065 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0431 afii10066 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0432 afii10067 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0433 afii10068 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0434 afii10069 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0435 afii10070 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0436 afii10072 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0437 afii10073 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0438 afii10074 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0439 afii10075 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+043a afii10076 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+043b afii10077 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+043c afii10078 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+043d afii10079 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+043e afii10080 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+043f afii10081 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0440 afii10082 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0441 afii10083 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0442 afii10084 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0443 afii10085 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0444 afii10086 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0445 afii10087 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0446 afii10088 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0447 afii10089 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0448 afii10090 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0449 afii10091 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+044a afii10092 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+044b afii10093 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+044c afii10094 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+044d afii10095 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+044e afii10096 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+044f afii10097 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0450 uni0450 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0451 afii10071 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0452 afii10099 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0453 afii10100 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0454 afii10101 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0455 afii10102 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0456 afii10103 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0457 afii10104 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0458 afii10105 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+0459 afii10106 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+045a afii10107 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+045b afii10108 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+045c afii10109 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+045d uni045D 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+045e afii10110 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) +U+045f afii10193 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) +U+0460 uni0460 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0461 uni0461 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0462 afii10146 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0463 afii10194 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0464 uni0464 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+0465 uni0465 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+0466 uni0466 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0467 uni0467 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0468 uni0468 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0469 uni0469 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046a uni046A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046b uni046B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046c uni046C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046d uni046D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046e uni046E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+046f uni046F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0470 uni0470 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0471 uni0471 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0472 afii10147 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+0473 afii10195 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0474 afii10148 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.12 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0475 afii10196 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.12 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0476 uni0476 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0477 uni0477 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0478 uni0478 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0479 uni0479 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047a uni047A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047b uni047B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047c uni047C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047d uni047D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047e uni047E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+047f uni047F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0480 uni0480 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0481 uni0481 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0482 uni0482 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0483 uni0483 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0484 uni0484 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0485 uni0485 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0486 uni0486 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0487 uni0487 2.9 (Sans, Sans Condensed) +U+0488 uni0488 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0489 uni0489 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+048a uni048A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+048b uni048B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+048c uni048C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+048d uni048D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+048e uni048E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+048f uni048F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0490 afii10050 1.15 +U+0491 afii10098 1.15 +U+0492 uni0492 1.14 +U+0493 uni0493 1.14 +U+0494 uni0494 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0495 uni0495 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0496 uni0496 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0497 uni0497 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0498 uni0498 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0499 uni0499 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+049a uni049A 1.14 +U+049b uni049B 1.14 +U+049c uni049C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+049d uni049D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+049e uni049E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+049f uni049F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a0 uni04A0 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a1 uni04A1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a2 uni04A2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a3 uni04A3 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a4 uni04A4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04a5 uni04A5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04a6 uni04A6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a7 uni04A7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a8 uni04A8 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04a9 uni04A9 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04aa uni04AA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04ab uni04AB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04ac uni04AC 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04ad uni04AD 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04ae uni04AE 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04af uni04AF 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04b0 uni04B0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04b1 uni04B1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04b2 uni04B2 1.14 +U+04b3 uni04B3 1.14 +U+04b4 uni04B4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04b5 uni04B5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04b6 uni04B6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04b7 uni04B7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04b8 uni04B8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04b9 uni04B9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04ba uni04BA 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04bb uni04BB 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04bc uni04BC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04bd uni04BD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04be uni04BE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04bf uni04BF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04c0 uni04C0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04c1 uni04C1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04c2 uni04C2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04c3 uni04C3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04c4 uni04C4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04c5 uni04C5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04c6 uni04C6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04c7 uni04C7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04c8 uni04C8 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04c9 uni04C9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04ca uni04CA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04cb uni04CB 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04cc uni04CC 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04cd uni04CD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04ce uni04CE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04cf uni04CF 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04d0 uni04D0 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d1 uni04D1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d2 uni04D2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d3 uni04D3 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d4 uni04D4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d5 uni04D5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d6 uni04D6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d7 uni04D7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04d8 uni04D8 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04d9 afii10846 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04da uni04DA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04db uni04DB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04dc uni04DC 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04dd uni04DD 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04de uni04DE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04df uni04DF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04e0 uni04E0 2.3 +U+04e1 uni04E1 2.3 +U+04e2 uni04E2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04e3 uni04E3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04e4 uni04E4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04e5 uni04E5 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04e6 uni04E6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04e7 uni04E7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) +U+04e8 uni04E8 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04e9 uni04E9 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04ea uni04EA 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04eb uni04EB 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+04ec uni04EC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04ed uni04ED 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04ee uni04EE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04ef uni04EF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f0 uni04F0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04f1 uni04F1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f2 uni04F2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04f3 uni04F3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f4 uni04F4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04f5 uni04F5 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04f6 uni04F6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f7 uni04F7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f8 uni04F8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04f9 uni04F9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+04fa uni04FA 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04fb uni04FB 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04fc uni04FC 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04fd uni04FD 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04fe uni04FE 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+04ff uni04FF 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0500 uni0500 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0501 uni0501 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0502 uni0502 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0503 uni0503 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0504 uni0504 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0505 uni0505 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0506 uni0506 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0507 uni0507 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0508 uni0508 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0509 uni0509 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050a uni050A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050b uni050B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050c uni050C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050d uni050D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050e uni050E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+050f uni050F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0510 uni0510 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0511 uni0511 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0512 uni0512 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0513 uni0513 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0531 uni0531 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0532 uni0532 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0533 uni0533 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0534 uni0534 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0535 uni0535 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0536 uni0536 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0537 uni0537 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0538 uni0538 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0539 uni0539 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053a uni053A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053b uni053B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053c uni053C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053d uni053D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053e uni053E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+053f uni053F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0540 uni0540 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0541 uni0541 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0542 uni0542 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0543 uni0543 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0544 uni0544 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0545 uni0545 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0546 uni0546 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0547 uni0547 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0548 uni0548 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+0549 uni0549 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+054a uni054A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+054b uni054B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+054c uni054C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+054d uni054D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+054e uni054E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+054f uni054F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0550 uni0550 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0551 uni0551 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0552 uni0552 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0553 uni0553 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+0554 uni0554 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0555 uni0555 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0556 uni0556 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0559 uni0559 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+055a uni055A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+055b uni055B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+055c uni055C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+055d uni055D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+055e uni055E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+055f uni055F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0561 uni0561 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+0562 uni0562 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0563 uni0563 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0564 uni0564 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0565 uni0565 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0566 uni0566 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0567 uni0567 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0568 uni0568 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0569 uni0569 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056a uni056A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056b uni056B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+056c uni056C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056d uni056D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+056e uni056E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056f uni056F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0570 uni0570 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0571 uni0571 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0572 uni0572 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0573 uni0573 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0574 uni0574 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0575 uni0575 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0576 uni0576 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0577 uni0577 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0578 uni0578 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0579 uni0579 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+057a uni057A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+057b uni057B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+057c uni057C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+057d uni057D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+057e uni057E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+057f uni057F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0580 uni0580 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0581 uni0581 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0582 uni0582 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0583 uni0583 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0584 uni0584 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0585 uni0585 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+0586 uni0586 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0587 uni0587 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0589 uni0589 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+058a uni058A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b0 afii57799 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b1 afii57801 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b2 afii57800 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b3 afii57802 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b4 afii57793 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b5 afii57794 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b6 afii57795 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b7 afii57798 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b8 afii57797 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05b9 afii57806 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05bb afii57796 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05bc afii57807 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05bd afii57839 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05be afii57645 2.9 (Sans Condensed Oblique, Sans Oblique) +U+05bf afii57841 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c0 afii57842 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c1 afii57804 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c2 afii57803 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c3 afii57658 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c6 uni05C6 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05c7 uni05C7 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d0 afii57664 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d1 afii57665 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d2 afii57666 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d3 afii57667 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d4 afii57668 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d5 afii57669 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d6 afii57670 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d7 afii57671 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d8 afii57672 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05d9 afii57673 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05da afii57674 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05db afii57675 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05dc afii57676 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05dd afii57677 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05de afii57678 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05df afii57679 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e0 afii57680 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e1 afii57681 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e2 afii57682 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e3 afii57683 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e4 afii57684 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e5 afii57685 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e6 afii57686 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e7 afii57687 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e8 afii57688 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05e9 afii57689 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05ea afii57690 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05f0 afii57716 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05f1 afii57717 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+05f2 afii57718 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+060c afii57388 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0615 uni0615 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+061b afii57403 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+061f afii57407 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0621 afii57409 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0622 afii57410 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0623 afii57411 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0624 afii57412 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0625 afii57413 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0626 afii57414 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0627 afii57415 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0628 afii57416 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0629 afii57417 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062a afii57418 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062b afii57419 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062c afii57420 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062d afii57421 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062e afii57422 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+062f afii57423 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0630 afii57424 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0631 afii57425 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0632 afii57426 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0633 afii57427 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0634 afii57428 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0635 afii57429 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0636 afii57430 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0637 afii57431 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0638 afii57432 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0639 afii57433 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+063a afii57434 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0640 afii57440 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0641 afii57441 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0642 afii57442 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0643 afii57443 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0644 afii57444 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0645 afii57445 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0646 afii57446 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0647 afii57470 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0648 afii57448 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0649 afii57449 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064a afii57450 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064b afii57451 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064c afii57452 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064d afii57453 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064e afii57454 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+064f afii57455 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0650 afii57456 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0651 afii57457 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0652 afii57458 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0653 uni0653 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0654 uni0654 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0655 uni0655 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+065a uni065A 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0660 afii57392 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0661 afii57393 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0662 afii57394 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0663 afii57395 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0664 afii57396 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0665 afii57397 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0666 afii57398 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0667 afii57399 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0668 afii57400 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0669 afii57401 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066a afii57381 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066b uni066B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066c uni066C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066d afii63167 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066e uni066E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+066f uni066F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0674 uni0674 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans ExtraLight) +U+0679 afii57511 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067a uni067A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067b uni067B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067c uni067C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067d uni067D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067e afii57506 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+067f uni067F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0680 uni0680 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0681 uni0681 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0682 uni0682 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0683 uni0683 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0684 uni0684 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0685 uni0685 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0686 afii57507 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0687 uni0687 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0691 afii57513 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0692 uni0692 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0695 uni0695 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0698 afii57508 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06a1 uni06A1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06a4 afii57505 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06a6 uni06A6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06a9 uni06A9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06af afii57509 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06b5 uni06B5 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06ba afii57514 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06bf uni06BF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06c6 uni06C6 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06cc uni06CC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06ce uni06CE 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06d5 uni06D5 2.10 (Sans, Sans Bold) 2.11 (Sans Condensed, Sans Condensed Bold) +U+06f0 uni06F0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f1 uni06F1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f2 uni06F2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f3 uni06F3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f4 uni06F4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f5 uni06F5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f6 uni06F6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f7 uni06F7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f8 uni06F8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06f9 uni06F9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0e3f uni0E3F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0e81 uni0E81 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e82 uni0E82 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e84 uni0E84 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e87 uni0E87 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e88 uni0E88 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e8a uni0E8A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e8d uni0E8D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e94 uni0E94 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e95 uni0E95 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e96 uni0E96 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e97 uni0E97 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e99 uni0E99 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9a uni0E9A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9b uni0E9B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9c uni0E9C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9d uni0E9D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9e uni0E9E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0e9f uni0E9F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ea1 uni0EA1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ea2 uni0EA2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ea3 uni0EA3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ea5 uni0EA5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ea7 uni0EA7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0eaa uni0EAA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0eab uni0EAB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0ead uni0EAD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0eae uni0EAE 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0eaf uni0EAF 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+0eb0 uni0EB0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb1 uni0EB1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb2 uni0EB2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb3 uni0EB3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb4 uni0EB4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb5 uni0EB5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb6 uni0EB6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb7 uni0EB7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb8 uni0EB8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eb9 uni0EB9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ebb uni0EBB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ebc uni0EBC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ebd uni0EBD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec0 uni0EC0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec1 uni0EC1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec2 uni0EC2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec3 uni0EC3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec4 uni0EC4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec6 uni0EC6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec8 uni0EC8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ec9 uni0EC9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0eca uni0ECA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ecb uni0ECB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ecc uni0ECC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0ecd uni0ECD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0edc uni0EDC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+0edd uni0EDD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1401 uni1401 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1402 uni1402 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1403 uni1403 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1404 uni1404 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1405 uni1405 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1406 uni1406 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1407 uni1407 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1409 uni1409 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140a uni140A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140b uni140B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140c uni140C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140d uni140D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140e uni140E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+140f uni140F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1410 uni1410 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1411 uni1411 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1412 uni1412 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1413 uni1413 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1414 uni1414 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1415 uni1415 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1416 uni1416 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1417 uni1417 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1418 uni1418 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1419 uni1419 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+141a uni141A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+141b uni141B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+141d uni141D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+141e uni141E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+141f uni141F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1420 uni1420 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1421 uni1421 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1422 uni1422 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1423 uni1423 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1424 uni1424 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1425 uni1425 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1426 uni1426 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1427 uni1427 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1428 uni1428 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1429 uni1429 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142a uni142A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142b uni142B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142c uni142C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142d uni142D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142e uni142E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+142f uni142F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1430 uni1430 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1431 uni1431 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1432 uni1432 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1433 uni1433 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1434 uni1434 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1435 uni1435 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1437 uni1437 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1438 uni1438 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1439 uni1439 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143a uni143A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143b uni143B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143c uni143C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143d uni143D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143e uni143E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+143f uni143F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1440 uni1440 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1441 uni1441 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1442 uni1442 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1443 uni1443 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1444 uni1444 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1445 uni1445 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1446 uni1446 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1447 uni1447 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1448 uni1448 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1449 uni1449 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+144a uni144A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+144c uni144C 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+144d uni144D 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+144e uni144E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+144f uni144F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1450 uni1450 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1451 uni1451 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1452 uni1452 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1454 uni1454 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1455 uni1455 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1456 uni1456 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1457 uni1457 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1458 uni1458 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1459 uni1459 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145a uni145A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145b uni145B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145c uni145C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145d uni145D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145e uni145E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+145f uni145F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1460 uni1460 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1461 uni1461 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1462 uni1462 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1463 uni1463 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1464 uni1464 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1465 uni1465 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1466 uni1466 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1467 uni1467 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1468 uni1468 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1469 uni1469 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146a uni146A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146b uni146B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146c uni146C 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146d uni146D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146e uni146E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+146f uni146F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1470 uni1470 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1471 uni1471 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1472 uni1472 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1473 uni1473 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1474 uni1474 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1475 uni1475 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1476 uni1476 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1477 uni1477 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1478 uni1478 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1479 uni1479 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147a uni147A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147b uni147B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147c uni147C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147d uni147D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147e uni147E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+147f uni147F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1480 uni1480 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1481 uni1481 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1482 uni1482 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1483 uni1483 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1484 uni1484 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1485 uni1485 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1486 uni1486 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1487 uni1487 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1488 uni1488 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1489 uni1489 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148a uni148A 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148b uni148B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148c uni148C 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148d uni148D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148e uni148E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+148f uni148F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1490 uni1490 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1491 uni1491 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1492 uni1492 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1493 uni1493 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1494 uni1494 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1495 uni1495 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1496 uni1496 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1497 uni1497 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1498 uni1498 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1499 uni1499 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149a uni149A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149b uni149B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149c uni149C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149d uni149D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149e uni149E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+149f uni149F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a0 uni14A0 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a1 uni14A1 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a2 uni14A2 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a3 uni14A3 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a4 uni14A4 2.13 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Oblique) 2.15 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+14a5 uni14A5 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a6 uni14A6 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a7 uni14A7 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a8 uni14A8 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14a9 uni14A9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14aa uni14AA 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ab uni14AB 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ac uni14AC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ad uni14AD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ae uni14AE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14af uni14AF 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b0 uni14B0 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b1 uni14B1 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b2 uni14B2 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b3 uni14B3 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b4 uni14B4 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b5 uni14B5 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b6 uni14B6 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b7 uni14B7 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b8 uni14B8 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14b9 uni14B9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ba uni14BA 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14bb uni14BB 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14bc uni14BC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14bd uni14BD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c0 uni14C0 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c1 uni14C1 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c2 uni14C2 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c3 uni14C3 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c4 uni14C4 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c5 uni14C5 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c6 uni14C6 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c7 uni14C7 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c8 uni14C8 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14c9 uni14C9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ca uni14CA 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14cb uni14CB 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14cc uni14CC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14cd uni14CD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ce uni14CE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14cf uni14CF 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d0 uni14D0 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d1 uni14D1 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d2 uni14D2 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d3 uni14D3 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d4 uni14D4 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d5 uni14D5 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d6 uni14D6 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d7 uni14D7 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d8 uni14D8 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14d9 uni14D9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14da uni14DA 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14db uni14DB 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14dc uni14DC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14dd uni14DD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14de uni14DE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14df uni14DF 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e0 uni14E0 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e1 uni14E1 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e2 uni14E2 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e3 uni14E3 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e4 uni14E4 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e5 uni14E5 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e6 uni14E6 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e7 uni14E7 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e8 uni14E8 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14e9 uni14E9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ea uni14EA 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ec uni14EC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ed uni14ED 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ee uni14EE 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ef uni14EF 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f0 uni14F0 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f1 uni14F1 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f2 uni14F2 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f3 uni14F3 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f4 uni14F4 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f5 uni14F5 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f6 uni14F6 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f7 uni14F7 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f8 uni14F8 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14f9 uni14F9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14fa uni14FA 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14fb uni14FB 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14fc uni14FC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14fd uni14FD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14fe uni14FE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+14ff uni14FF 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1500 uni1500 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1501 uni1501 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1502 uni1502 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1503 uni1503 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1504 uni1504 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1505 uni1505 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1506 uni1506 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1507 uni1507 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1510 uni1510 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1511 uni1511 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1512 uni1512 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1513 uni1513 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1514 uni1514 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1515 uni1515 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1516 uni1516 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1517 uni1517 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1518 uni1518 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1519 uni1519 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151a uni151A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151b uni151B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151c uni151C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151d uni151D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151e uni151E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+151f uni151F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1520 uni1520 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1521 uni1521 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1522 uni1522 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1523 uni1523 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1524 uni1524 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1525 uni1525 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1526 uni1526 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1527 uni1527 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1528 uni1528 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1529 uni1529 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152a uni152A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152b uni152B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152c uni152C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152d uni152D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152e uni152E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+152f uni152F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1530 uni1530 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1531 uni1531 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1532 uni1532 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1533 uni1533 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1534 uni1534 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1535 uni1535 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1536 uni1536 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1537 uni1537 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1538 uni1538 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1539 uni1539 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+153a uni153A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+153b uni153B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+153c uni153C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+153d uni153D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+153e uni153E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1540 uni1540 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1541 uni1541 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1542 uni1542 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1543 uni1543 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1544 uni1544 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1545 uni1545 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1546 uni1546 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1547 uni1547 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1548 uni1548 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1549 uni1549 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154a uni154A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154b uni154B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154c uni154C 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154d uni154D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154e uni154E 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+154f uni154F 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1550 uni1550 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1552 uni1552 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1553 uni1553 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1554 uni1554 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1555 uni1555 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1556 uni1556 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1557 uni1557 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1558 uni1558 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1559 uni1559 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155a uni155A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155b uni155B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155c uni155C 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155d uni155D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155e uni155E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+155f uni155F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1560 uni1560 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1561 uni1561 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1562 uni1562 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1563 uni1563 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1564 uni1564 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1565 uni1565 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1566 uni1566 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1567 uni1567 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1568 uni1568 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1569 uni1569 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+156a uni156A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1574 uni1574 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1575 uni1575 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1576 uni1576 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1577 uni1577 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1578 uni1578 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1579 uni1579 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157a uni157A 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157b uni157B 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157c uni157C 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157d uni157D 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157e uni157E 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+157f uni157F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1580 uni1580 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1581 uni1581 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1582 uni1582 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1583 uni1583 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1584 uni1584 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1585 uni1585 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158a uni158A 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158b uni158B 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158c uni158C 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158d uni158D 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158e uni158E 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+158f uni158F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1590 uni1590 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1591 uni1591 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1592 uni1592 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1593 uni1593 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1594 uni1594 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1595 uni1595 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1596 uni1596 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a0 uni15A0 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a1 uni15A1 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a2 uni15A2 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a3 uni15A3 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a4 uni15A4 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a5 uni15A5 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a6 uni15A6 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a7 uni15A7 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a8 uni15A8 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15a9 uni15A9 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15aa uni15AA 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15ab uni15AB 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15ac uni15AC 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15ad uni15AD 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15ae uni15AE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15af uni15AF 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15de uni15DE 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+15e1 uni15E1 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1646 uni1646 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1647 uni1647 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+166e uni166E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+166f uni166F 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1670 uni1670 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1671 uni1671 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1672 uni1672 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1673 uni1673 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1674 uni1674 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1675 uni1675 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1676 uni1676 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d00 uni1D00 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d01 uni1D01 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d02 uni1D02 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+1d03 uni1D03 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d04 uni1D04 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d05 uni1D05 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d06 uni1D06 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d07 uni1D07 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d08 uni1D08 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1d09 uni1D09 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+1d0a uni1D0A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d0b uni1D0B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d0c uni1D0C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d0d uni1D0D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d0e uni1D0E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d0f uni1D0F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d10 uni1D10 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d11 uni1D11 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d12 uni1D12 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d13 uni1D13 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d14 uni1D14 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+1d16 uni1D16 2.3 +U+1d17 uni1D17 2.3 +U+1d18 uni1D18 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d19 uni1D19 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d1a uni1D1A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d1b uni1D1B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d1c uni1D1C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d1d uni1D1D 2.3 +U+1d1e uni1D1E 2.3 +U+1d1f uni1D1F 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1d20 uni1D20 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d21 uni1D21 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d22 uni1D22 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d23 uni1D23 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d26 uni1D26 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d27 uni1D27 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d28 uni1D28 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d29 uni1D29 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d2a uni1D2A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d2b uni1D2B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d2c uni1D2C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d2d uni1D2D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d2e uni1D2E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d30 uni1D30 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d31 uni1D31 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d32 uni1D32 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d33 uni1D33 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d34 uni1D34 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d35 uni1D35 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d36 uni1D36 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d37 uni1D37 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d38 uni1D38 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d39 uni1D39 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3a uni1D3A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3b uni1D3B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3c uni1D3C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3d uni1D3D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3e uni1D3E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d3f uni1D3F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d40 uni1D40 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d41 uni1D41 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d42 uni1D42 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d43 uni1D43 2.3 +U+1d44 uni1D44 2.3 +U+1d45 uni1D45 2.3 +U+1d46 uni1D46 2.3 +U+1d47 uni1D47 2.3 +U+1d48 uni1D48 2.3 +U+1d49 uni1D49 2.3 +U+1d4a uni1D4A 2.3 +U+1d4b uni1D4B 2.3 +U+1d4c uni1D4C 2.3 +U+1d4d uni1D4D 2.3 +U+1d4e uni1D4E 2.3 +U+1d4f uni1D4F 2.3 +U+1d50 uni1D50 2.3 +U+1d51 uni1D51 2.3 +U+1d52 uni1D52 2.3 +U+1d53 uni1D53 2.3 +U+1d54 uni1D54 2.3 +U+1d55 uni1D55 2.3 +U+1d56 uni1D56 2.3 +U+1d57 uni1D57 2.3 +U+1d58 uni1D58 2.3 +U+1d59 uni1D59 2.3 +U+1d5a uni1D5A 2.3 +U+1d5b uni1D5B 2.3 +U+1d5c uni1D5C 2.10 (Sans Oblique) 2.11 (Sans Condensed Oblique) +U+1d5d uni1D5D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d5e uni1D5E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d5f uni1D5F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d60 uni1D60 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d61 uni1D61 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d62 uni1D62 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d63 uni1D63 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d64 uni1D64 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d65 uni1D65 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d66 uni1D66 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d67 uni1D67 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d68 uni1D68 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d69 uni1D69 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d6a uni1D6A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d77 uni1D77 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+1d78 uni1D78 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1d7b uni1D7B 2.3 +U+1d85 uni1D85 2.3 +U+1d9b uni1D9B 2.3 +U+1d9c uni1D9C 2.3 +U+1d9d uni1D9D 2.3 +U+1d9e uni1D9E 2.3 +U+1d9f uni1D9F 2.3 +U+1da0 uni1DA0 2.3 +U+1da1 uni1DA1 2.3 +U+1da2 uni1DA2 2.3 +U+1da3 uni1DA3 2.3 +U+1da4 uni1DA4 2.3 +U+1da5 uni1DA5 2.3 +U+1da6 uni1DA6 2.3 +U+1da7 uni1DA7 2.3 +U+1da8 uni1DA8 2.3 +U+1da9 uni1DA9 2.3 +U+1daa uni1DAA 2.3 +U+1dab uni1DAB 2.3 +U+1dac uni1DAC 2.3 +U+1dad uni1DAD 2.3 +U+1dae uni1DAE 2.3 +U+1daf uni1DAF 2.3 +U+1db0 uni1DB0 2.3 +U+1db1 uni1DB1 2.3 +U+1db2 uni1DB2 2.3 +U+1db3 uni1DB3 2.3 +U+1db4 uni1DB4 2.3 +U+1db5 uni1DB5 2.3 +U+1db6 uni1DB6 2.3 +U+1db7 uni1DB7 2.3 +U+1db8 uni1DB8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+1db9 uni1DB9 2.3 +U+1dba uni1DBA 2.3 +U+1dbb uni1DBB 2.3 +U+1dbc uni1DBC 2.3 +U+1dbd uni1DBD 2.3 +U+1dbe uni1DBE 2.3 +U+1dbf uni1DBF 2.3 +U+1dc4 uni1DC4 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1dc5 uni1DC5 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1dc6 uni1DC6 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1dc7 uni1DC7 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1dc8 uni1DC8 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1dc9 uni1DC9 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1e00 uni1E00 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e01 uni1E01 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e02 uni1E02 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e03 uni1E03 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e04 uni1E04 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e05 uni1E05 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e06 uni1E06 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e07 uni1E07 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e08 uni1E08 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e09 uni1E09 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e0a uni1E0A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e0b uni1E0B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e0c uni1E0C 2.1 +U+1e0d uni1E0D 2.1 +U+1e0e uni1E0E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e0f uni1E0F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e10 uni1E10 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e11 uni1E11 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e12 uni1E12 1.13 +U+1e13 uni1E13 1.13 +U+1e14 uni1E14 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e15 uni1E15 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e16 uni1E16 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e17 uni1E17 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e18 uni1E18 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e19 uni1E19 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1a uni1E1A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1b uni1E1B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1c uni1E1C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1d uni1E1D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1e uni1E1E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e1f uni1E1F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e20 uni1E20 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e21 uni1E21 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e22 uni1E22 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e23 uni1E23 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e24 uni1E24 2.1 +U+1e25 uni1E25 2.1 +U+1e26 uni1E26 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e27 uni1E27 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e28 uni1E28 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e29 uni1E29 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e2a uni1E2A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e2b uni1E2B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e2c uni1E2C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e2d uni1E2D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e2e uni1E2E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e2f uni1E2F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e30 uni1E30 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e31 uni1E31 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e32 uni1E32 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e33 uni1E33 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e34 uni1E34 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e35 uni1E35 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e36 uni1E36 2.1 +U+1e37 uni1E37 2.1 +U+1e38 uni1E38 2.1 +U+1e39 uni1E39 2.1 +U+1e3a uni1E3A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e3b uni1E3B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e3c uni1E3C 1.13 +U+1e3d uni1E3D 1.13 +U+1e3e uni1E3E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e3f uni1E3F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e40 uni1E40 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e41 uni1E41 2.1 +U+1e42 uni1E42 2.1 +U+1e43 uni1E43 2.1 +U+1e44 uni1E44 1.13 +U+1e45 uni1E45 1.13 +U+1e46 uni1E46 2.1 +U+1e47 uni1E47 2.1 +U+1e48 uni1E48 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e49 uni1E49 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e4a uni1E4A 1.13 +U+1e4b uni1E4B 1.13 +U+1e4c uni1E4C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e4d uni1E4D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e4e uni1E4E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e4f uni1E4F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e50 uni1E50 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e51 uni1E51 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e52 uni1E52 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e53 uni1E53 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e54 uni1E54 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e55 uni1E55 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e56 uni1E56 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e57 uni1E57 2.1 +U+1e58 uni1E58 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e59 uni1E59 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e5a uni1E5A 2.1 +U+1e5b uni1E5B 2.1 +U+1e5c uni1E5C 2.1 +U+1e5d uni1E5D 2.1 +U+1e5e uni1E5E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e5f uni1E5F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e60 uni1E60 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e61 uni1E61 2.1 +U+1e62 uni1E62 2.1 +U+1e63 uni1E63 2.1 +U+1e64 uni1E64 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1e65 uni1E65 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1e66 uni1E66 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e67 uni1E67 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1e68 uni1E68 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e69 uni1E69 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e6a uni1E6A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e6b uni1E6B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e6c uni1E6C 2.1 +U+1e6d uni1E6D 2.1 +U+1e6e uni1E6E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e6f uni1E6F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e70 uni1E70 1.13 +U+1e71 uni1E71 1.13 +U+1e72 uni1E72 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e73 uni1E73 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e74 uni1E74 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e75 uni1E75 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e76 uni1E76 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e77 uni1E77 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e78 uni1E78 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e79 uni1E79 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e7a uni1E7A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e7b uni1E7B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1e7c uni1E7C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e7d uni1E7D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e7e uni1E7E 2.1 +U+1e7f uni1E7F 2.1 +U+1e80 Wgrave 1.2 +U+1e81 wgrave 1.2 +U+1e82 Wacute 1.2 +U+1e83 wacute 1.2 +U+1e84 Wdieresis 1.2 +U+1e85 wdieresis 1.2 +U+1e86 uni1E86 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e87 uni1E87 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e88 uni1E88 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e89 uni1E89 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e8a uni1E8A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e8b uni1E8B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e8c uni1E8C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e8d uni1E8D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e8e uni1E8E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e8f uni1E8F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e90 uni1E90 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e91 uni1E91 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e92 uni1E92 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e93 uni1E93 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e94 uni1E94 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e95 uni1E95 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e96 uni1E96 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1e97 uni1E97 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e98 uni1E98 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e99 uni1E99 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e9a uni1E9A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+1e9b uni1E9B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ea0 uni1EA0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ea1 uni1EA1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ea2 uni1EA2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ea3 uni1EA3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ea4 uni1EA4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ea5 uni1EA5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ea6 uni1EA6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ea7 uni1EA7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ea8 uni1EA8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ea9 uni1EA9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1eaa uni1EAA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1eab uni1EAB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1eac uni1EAC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1ead uni1EAD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1eae uni1EAE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eaf uni1EAF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb0 uni1EB0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb1 uni1EB1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb2 uni1EB2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb3 uni1EB3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb4 uni1EB4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb5 uni1EB5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eb6 uni1EB6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1eb7 uni1EB7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1eb8 uni1EB8 2.2 +U+1eb9 uni1EB9 2.2 +U+1eba uni1EBA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ebb uni1EBB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ebc uni1EBC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ebd uni1EBD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ebe uni1EBE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ebf uni1EBF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec0 uni1EC0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec1 uni1EC1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec2 uni1EC2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec3 uni1EC3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec4 uni1EC4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec5 uni1EC5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ec6 uni1EC6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1ec7 uni1EC7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1ec8 uni1EC8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ec9 uni1EC9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1eca uni1ECA 2.2 +U+1ecb uni1ECB 2.2 +U+1ecc uni1ECC 2.2 +U+1ecd uni1ECD 2.2 +U+1ece uni1ECE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ecf uni1ECF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ed0 uni1ED0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed1 uni1ED1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed2 uni1ED2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed3 uni1ED3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed4 uni1ED4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed5 uni1ED5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed6 uni1ED6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed7 uni1ED7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ed8 uni1ED8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1ed9 uni1ED9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1eda uni1EDA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1edb uni1EDB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1edc uni1EDC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1edd uni1EDD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ede uni1EDE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1edf uni1EDF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1ee0 uni1EE0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ee1 uni1EE1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ee2 uni1EE2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ee3 uni1EE3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ee4 uni1EE4 2.2 +U+1ee5 uni1EE5 2.2 +U+1ee6 uni1EE6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ee7 uni1EE7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ee8 uni1EE8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ee9 uni1EE9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1eea uni1EEA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1eeb uni1EEB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1eec uni1EEC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1eed uni1EED 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+1eee uni1EEE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1eef uni1EEF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ef0 uni1EF0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ef1 uni1EF1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+1ef2 Ygrave 1.2 +U+1ef3 ygrave 1.2 +U+1ef4 uni1EF4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ef5 uni1EF5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ef6 uni1EF6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ef7 uni1EF7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans ExtraLight) +U+1ef8 uni1EF8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ef9 uni1EF9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f00 uni1F00 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f01 uni1F01 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f02 uni1F02 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f03 uni1F03 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f04 uni1F04 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f05 uni1F05 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f06 uni1F06 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f07 uni1F07 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f08 uni1F08 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f09 uni1F09 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0a uni1F0A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0b uni1F0B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0c uni1F0C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0d uni1F0D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0e uni1F0E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f0f uni1F0F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f10 uni1F10 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f11 uni1F11 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f12 uni1F12 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f13 uni1F13 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f14 uni1F14 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f15 uni1F15 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f18 uni1F18 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f19 uni1F19 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f1a uni1F1A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f1b uni1F1B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f1c uni1F1C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f1d uni1F1D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f20 uni1F20 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f21 uni1F21 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f22 uni1F22 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f23 uni1F23 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f24 uni1F24 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f25 uni1F25 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f26 uni1F26 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f27 uni1F27 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f28 uni1F28 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f29 uni1F29 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2a uni1F2A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2b uni1F2B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2c uni1F2C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2d uni1F2D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2e uni1F2E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f2f uni1F2F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f30 uni1F30 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f31 uni1F31 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f32 uni1F32 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f33 uni1F33 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f34 uni1F34 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f35 uni1F35 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f36 uni1F36 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f37 uni1F37 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f38 uni1F38 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f39 uni1F39 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3a uni1F3A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3b uni1F3B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3c uni1F3C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3d uni1F3D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3e uni1F3E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f3f uni1F3F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f40 uni1F40 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f41 uni1F41 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f42 uni1F42 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f43 uni1F43 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f44 uni1F44 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f45 uni1F45 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f48 uni1F48 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f49 uni1F49 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f4a uni1F4A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f4b uni1F4B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f4c uni1F4C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f4d uni1F4D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f50 uni1F50 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f51 uni1F51 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f52 uni1F52 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f53 uni1F53 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f54 uni1F54 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f55 uni1F55 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f56 uni1F56 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f57 uni1F57 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f59 uni1F59 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f5b uni1F5B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f5d uni1F5D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f5f uni1F5F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f60 uni1F60 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f61 uni1F61 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f62 uni1F62 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f63 uni1F63 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f64 uni1F64 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f65 uni1F65 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f66 uni1F66 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f67 uni1F67 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f68 uni1F68 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f69 uni1F69 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6a uni1F6A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6b uni1F6B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6c uni1F6C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6d uni1F6D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6e uni1F6E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f6f uni1F6F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f70 uni1F70 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f71 uni1F71 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f72 uni1F72 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f73 uni1F73 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f74 uni1F74 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f75 uni1F75 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f76 uni1F76 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f77 uni1F77 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f78 uni1F78 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f79 uni1F79 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1f7a uni1F7A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f7b uni1F7B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f7c uni1F7C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f7d uni1F7D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f80 uni1F80 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f81 uni1F81 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f82 uni1F82 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f83 uni1F83 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f84 uni1F84 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f85 uni1F85 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f86 uni1F86 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f87 uni1F87 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f88 uni1F88 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f89 uni1F89 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8a uni1F8A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8b uni1F8B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8c uni1F8C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8d uni1F8D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8e uni1F8E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f8f uni1F8F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f90 uni1F90 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f91 uni1F91 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f92 uni1F92 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f93 uni1F93 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f94 uni1F94 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f95 uni1F95 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f96 uni1F96 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f97 uni1F97 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f98 uni1F98 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f99 uni1F99 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9a uni1F9A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9b uni1F9B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9c uni1F9C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9d uni1F9D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9e uni1F9E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1f9f uni1F9F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa0 uni1FA0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa1 uni1FA1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa2 uni1FA2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa3 uni1FA3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa4 uni1FA4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa5 uni1FA5 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa6 uni1FA6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa7 uni1FA7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa8 uni1FA8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fa9 uni1FA9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1faa uni1FAA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fab uni1FAB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fac uni1FAC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fad uni1FAD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fae uni1FAE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1faf uni1FAF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb0 uni1FB0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb1 uni1FB1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb2 uni1FB2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb3 uni1FB3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb4 uni1FB4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb6 uni1FB6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb7 uni1FB7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fb8 uni1FB8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fb9 uni1FB9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fba uni1FBA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fbb uni1FBB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fbc uni1FBC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fbd uni1FBD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fbe uni1FBE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fbf uni1FBF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fc0 uni1FC0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fc1 uni1FC1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fc2 uni1FC2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fc3 uni1FC3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fc4 uni1FC4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fc6 uni1FC6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fc7 uni1FC7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fc8 uni1FC8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fc9 uni1FC9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fca uni1FCA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fcb uni1FCB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fcc uni1FCC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.10 (Sans ExtraLight) +U+1fcd uni1FCD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fce uni1FCE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fcf uni1FCF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd0 uni1FD0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd1 uni1FD1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd2 uni1FD2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd3 uni1FD3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd6 uni1FD6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd7 uni1FD7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fd8 uni1FD8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fd9 uni1FD9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fda uni1FDA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fdb uni1FDB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fdd uni1FDD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fde uni1FDE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fdf uni1FDF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe0 uni1FE0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe1 uni1FE1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe2 uni1FE2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe3 uni1FE3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe4 uni1FE4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe5 uni1FE5 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe6 uni1FE6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe7 uni1FE7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fe8 uni1FE8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fe9 uni1FE9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fea uni1FEA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1feb uni1FEB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fec uni1FEC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1fed uni1FED 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fee uni1FEE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fef uni1FEF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ff2 uni1FF2 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ff3 uni1FF3 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ff4 uni1FF4 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ff6 uni1FF6 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ff7 uni1FF7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ff8 uni1FF8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ff9 uni1FF9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ffa uni1FFA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ffb uni1FFB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.10 (Sans ExtraLight) +U+1ffc uni1FFC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+1ffd uni1FFD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ffe uni1FFE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) +U+2000 uni2000 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2001 uni2001 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2002 uni2002 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2003 uni2003 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2004 uni2004 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2005 uni2005 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2006 uni2006 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2007 uni2007 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2008 uni2008 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2009 uni2009 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+200a uni200A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+200b uni200B 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.8 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+200c afii61664 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.8 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+200d afii301 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.8 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+200e afii299 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.8 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+200f afii300 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.8 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2010 uni2010 1.5 +U+2011 uni2011 1.5 +U+2012 figuredash 1.5 +U+2013 endash original +U+2014 emdash original +U+2015 afii00208 1.5 +U+2016 uni2016 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2017 underscoredbl 2.3 +U+2018 quoteleft original +U+2019 quoteright original +U+201a quotesinglbase original +U+201b quotereversed 2.3 +U+201c quotedblleft original +U+201d quotedblright original +U+201e quotedblbase original +U+201f uni201F 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+2020 dagger original +U+2021 daggerdbl original +U+2022 bullet original +U+2023 uni2023 2.2 +U+2024 onedotenleader 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2025 twodotenleader 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2026 ellipsis original +U+2027 uni2027 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+202a uni202A 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+202b uni202B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+202c afii61573 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+202d afii61574 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+202e afii61575 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+202f uni202F 2.11 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2030 perthousand original +U+2031 uni2031 2.1 +U+2032 minute 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2033 second 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2034 uni2034 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2035 uni2035 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2036 uni2036 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2037 uni2037 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2038 uni2038 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2039 guilsinglleft original +U+203a guilsinglright original +U+203b uni203B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+203c exclamdbl 2.0 +U+203d uni203D 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.11 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.14 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+203e uni203E 2.3 +U+203f uni203F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2040 uni2040 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2041 uni2041 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2042 uni2042 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2043 uni2043 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2044 fraction 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2045 uni2045 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2046 uni2046 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2047 uni2047 2.0 +U+2048 uni2048 2.0 +U+2049 uni2049 2.0 +U+204a uni204A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+204b uni204B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+204c uni204C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+204d uni204D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+204e uni204E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+204f uni204F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2050 uni2050 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2051 uni2051 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2052 uni2052 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2053 uni2053 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2054 uni2054 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2055 uni2055 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2056 uni2056 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2057 uni2057 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2058 uni2058 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2059 uni2059 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205a uni205A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205b uni205B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205c uni205C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205d uni205D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205e uni205E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+205f uni205F 2.14 +U+2060 uni2060 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2061 uni2061 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2062 uni2062 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2063 uni2063 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206a uni206A 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206b uni206B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206c uni206C 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206d uni206D 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206e uni206E 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+206f uni206F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2070 uni2070 2.2 +U+2071 uni2071 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2074 uni2074 2.2 +U+2075 uni2075 2.2 +U+2076 uni2076 2.2 +U+2077 uni2077 2.2 +U+2078 uni2078 2.2 +U+2079 uni2079 2.2 +U+207a uni207A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+207b uni207B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+207c uni207C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+207d uni207D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+207e uni207E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+207f uni207F 1.14 +U+2080 uni2080 2.4 +U+2081 uni2081 2.4 +U+2082 uni2082 2.4 +U+2083 uni2083 2.4 +U+2084 uni2084 2.4 +U+2085 uni2085 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2086 uni2086 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2087 uni2087 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2088 uni2088 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2089 uni2089 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+208a uni208A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+208b uni208B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+208c uni208C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+208d uni208D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+208e uni208E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2090 uni2090 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2091 uni2091 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2092 uni2092 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2093 uni2093 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2094 uni2094 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20a0 uni20A0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a1 colonmonetary 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a2 uni20A2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a3 franc 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a4 lira 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a5 uni20A5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a6 uni20A6 2.3 +U+20a7 peseta 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a8 uni20A8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20a9 uni20A9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20aa afii57636 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20ab dong 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+20ac Euro original +U+20ad uni20AD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20ae uni20AE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20af uni20AF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+20b0 uni20B0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20b1 uni20B1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.14 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+20b2 uni20B2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20b3 uni20B3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20b4 uni20B4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+20b5 uni20B5 2.2 +U+20d0 uni20D0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20d1 uni20D1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+20d6 uni20D6 2.8 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20d7 uni20D7 2.8 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2100 uni2100 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2101 uni2101 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2102 uni2102 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2103 uni2103 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2104 uni2104 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2105 afii61248 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2106 uni2106 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2107 uni2107 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2108 uni2108 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2109 uni2109 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+210b uni210B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+210c uni210C 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+210d uni210D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+210e uni210E 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+210f uni210F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2110 uni2110 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2111 Ifraktur 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2112 uni2112 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2113 afii61289 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2114 uni2114 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2115 uni2115 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2116 afii61352 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2117 uni2117 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2118 weierstrass 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2119 uni2119 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+211a uni211A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+211b uni211B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+211c Rfraktur 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+211d uni211D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+211e prescription 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+211f uni211F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2120 uni2120 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2121 uni2121 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2122 trademark original +U+2123 uni2123 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2124 uni2124 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2125 uni2125 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2126 uni2126 2.2 +U+2127 uni2127 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2128 uni2128 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2129 uni2129 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+212a uni212A 2.2 +U+212b uni212B 2.2 +U+212c uni212C 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+212d uni212D 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+212e estimated 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+212f uni212F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2130 uni2130 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2131 uni2131 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2132 uni2132 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+2133 uni2133 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2134 uni2134 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2135 aleph 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2136 uni2136 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2137 uni2137 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2138 uni2138 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2139 uni2139 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+213a uni213A 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+213b uni213B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+213c uni213C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+213d uni213D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+213e uni213E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+213f uni213F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2140 uni2140 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2141 uni2141 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2142 uni2142 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2143 uni2143 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2144 uni2144 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2145 uni2145 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2146 uni2146 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2147 uni2147 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2148 uni2148 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2149 uni2149 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+214b uni214B 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+214e uni214E 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2153 onethird 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2154 twothirds 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2155 uni2155 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2156 uni2156 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2157 uni2157 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2158 uni2158 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2159 uni2159 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215a uni215A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215b oneeighth 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215c threeeighths 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215d fiveeighths 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215e seveneighths 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+215f uni215F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2160 uni2160 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2161 uni2161 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2162 uni2162 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2163 uni2163 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2164 uni2164 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2165 uni2165 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2166 uni2166 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2167 uni2167 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2168 uni2168 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2169 uni2169 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216a uni216A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216b uni216B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216c uni216C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216d uni216D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216e uni216E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+216f uni216F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2170 uni2170 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2171 uni2171 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2172 uni2172 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2173 uni2173 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2174 uni2174 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2175 uni2175 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2176 uni2176 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2177 uni2177 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2178 uni2178 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2179 uni2179 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217a uni217A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217b uni217B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217c uni217C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217d uni217D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217e uni217E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+217f uni217F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2180 uni2180 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+2181 uni2181 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2182 uni2182 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2183 uni2183 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) +U+2184 uni2184 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+2190 arrowleft 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2191 arrowup 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2192 arrowright 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2193 arrowdown 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2194 arrowboth 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2195 arrowupdn 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2196 uni2196 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2197 uni2197 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2198 uni2198 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2199 uni2199 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219a uni219A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219b uni219B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219c uni219C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219d uni219D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219e uni219E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+219f uni219F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a0 uni21A0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a1 uni21A1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a2 uni21A2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a3 uni21A3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a4 uni21A4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a5 uni21A5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a6 uni21A6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a7 uni21A7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a8 arrowupdnbse 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21a9 uni21A9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21aa uni21AA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ab uni21AB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ac uni21AC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ad uni21AD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ae uni21AE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21af uni21AF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b0 uni21B0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b1 uni21B1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b2 uni21B2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b3 uni21B3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b4 uni21B4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b5 carriagereturn 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b6 uni21B6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b7 uni21B7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b8 uni21B8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21b9 uni21B9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ba uni21BA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21bb uni21BB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21bc uni21BC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21bd uni21BD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21be uni21BE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21bf uni21BF 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c0 uni21C0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c1 uni21C1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c2 uni21C2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c3 uni21C3 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c4 uni21C4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c5 uni21C5 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c6 uni21C6 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c7 uni21C7 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c8 uni21C8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21c9 uni21C9 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ca uni21CA 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21cb uni21CB 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21cc uni21CC 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21cd uni21CD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ce uni21CE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21cf uni21CF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d0 arrowdblleft 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d1 arrowdblup 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d2 arrowdblright 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d3 arrowdbldown 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d4 arrowdblboth 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d5 uni21D5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d6 uni21D6 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d7 uni21D7 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d8 uni21D8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21d9 uni21D9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21da uni21DA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21db uni21DB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21dc uni21DC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21dd uni21DD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21de uni21DE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21df uni21DF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e0 uni21E0 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e1 uni21E1 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e2 uni21E2 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e3 uni21E3 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e4 uni21E4 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e5 uni21E5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e6 uni21E6 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e7 uni21E7 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e8 uni21E8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21e9 uni21E9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ea uni21EA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21eb uni21EB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ec uni21EC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ed uni21ED 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ee uni21EE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ef uni21EF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f0 uni21F0 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f1 uni21F1 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f2 uni21F2 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f3 uni21F3 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f4 uni21F4 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f5 uni21F5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f6 uni21F6 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f7 uni21F7 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f8 uni21F8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21f9 uni21F9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21fa uni21FA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21fb uni21FB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21fc uni21FC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21fd uni21FD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21fe uni21FE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+21ff uni21FF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2200 universal 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+2201 uni2201 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2202 partialdiff original +U+2203 existential 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+2204 uni2204 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2205 emptyset 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2206 Delta original +U+2207 gradient 2.1 +U+2208 element 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2209 notelement 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+220a uni220A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+220b suchthat 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+220c uni220C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+220d uni220D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+220e uni220E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+220f product original +U+2210 uni2210 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2211 summation original +U+2212 minus original +U+2213 uni2213 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2214 uni2214 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2215 fraction original +U+2216 uni2216 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2217 asteriskmath 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2218 uni2218 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2219 periodcentered original +U+221a radical original +U+221b uni221B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+221c uni221C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+221d proportional 2.1 +U+221e infinity original +U+221f orthogonal 2.1 +U+2220 angle 2.3 +U+2221 uni2221 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2222 uni2222 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2223 uni2223 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2224 uni2224 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2225 uni2225 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2226 uni2226 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2227 logicaland 2.1 +U+2228 logicalor 2.1 +U+2229 intersection 2.1 +U+222a union 2.1 +U+222b integral original +U+222c uni222C 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+222d uni222D 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+222e uni222E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+222f uni222F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2230 uni2230 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2231 uni2231 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2232 uni2232 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2233 uni2233 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2234 therefore 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2235 uni2235 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2236 uni2236 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2237 uni2237 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2238 uni2238 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2239 uni2239 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+223a uni223A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+223b uni223B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+223c similar 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+223d uni223D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+223e uni223E 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+223f uni223F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2240 uni2240 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2241 uni2241 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2242 uni2242 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2243 uni2243 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2244 uni2244 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2245 congruent 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2246 uni2246 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2247 uni2247 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2248 approxequal original +U+2249 uni2249 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224a uni224A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224b uni224B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224c uni224C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224d uni224D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224e uni224E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+224f uni224F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2250 uni2250 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2251 uni2251 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2252 uni2252 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2253 uni2253 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2254 uni2254 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2255 uni2255 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2256 uni2256 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2257 uni2257 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2258 uni2258 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2259 uni2259 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225a uni225A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225b uni225B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225c uni225C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225d uni225D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225e uni225E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+225f uni225F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2260 notequal original +U+2261 equivalence 2.1 +U+2262 uni2262 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2263 uni2263 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2264 lessequal original +U+2265 greaterequal original +U+2266 uni2266 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2267 uni2267 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2268 uni2268 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2269 uni2269 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+226a uni226A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+226b uni226B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+226c uni226C 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+226d uni226D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+226e uni226E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+226f uni226F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2270 uni2270 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2271 uni2271 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2272 uni2272 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2273 uni2273 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2274 uni2274 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2275 uni2275 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2276 uni2276 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2277 uni2277 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2278 uni2278 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2279 uni2279 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227a uni227A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227b uni227B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227c uni227C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227d uni227D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227e uni227E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+227f uni227F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2280 uni2280 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2281 uni2281 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2282 propersubset 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2283 propersuperset 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2284 notsubset 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2285 uni2285 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2286 reflexsubset 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2287 reflexsuperset 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2288 uni2288 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2289 uni2289 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+228a uni228A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+228b uni228B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.6 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+228c uni228C 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+228d uni228D 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+228e uni228E 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+228f uni228F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2290 uni2290 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2291 uni2291 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2292 uni2292 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+2293 uni2293 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2294 uni2294 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2295 circleplus 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2296 uni2296 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2297 circlemultiply 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2298 uni2298 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2299 uni2299 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229a uni229A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229b uni229B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229c uni229C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229d uni229D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229e uni229E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+229f uni229F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22a0 uni22A0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22a1 uni22A1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22a2 uni22A2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a3 uni22A3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a4 uni22A4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a5 perpendicular 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a6 uni22A6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a7 uni22A7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a8 uni22A8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22a9 uni22A9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22aa uni22AA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ab uni22AB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ac uni22AC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ad uni22AD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ae uni22AE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22af uni22AF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b2 uni22B2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b3 uni22B3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b4 uni22B4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b5 uni22B5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b6 uni22B6 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b7 uni22B7 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b8 uni22B8 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22b9 uni22B9 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ba uni22BA 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22bb uni22BB 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22bc uni22BC 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22bd uni22BD 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c0 uni22C0 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c1 uni22C1 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c2 uni22C2 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c3 uni22C3 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c4 uni22C4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c5 dotmath 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22c6 uni22C6 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22c8 uni22C8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22c9 uni22C9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ca uni22CA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22cb uni22CB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22cc uni22CC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22cd uni22CD 2.6 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) 2.7 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+22d6 uni22D6 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22d7 uni22D7 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22d8 uni22D8 2.6 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+22d9 uni22D9 2.6 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+22da uni22DA 2.6 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) 2.7 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+22db uni22DB 2.6 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) 2.7 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+22dc uni22DC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22dd uni22DD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22de uni22DE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22df uni22DF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e0 uni22E0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e1 uni22E1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e2 uni22E2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e3 uni22E3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e4 uni22E4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e5 uni22E5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e6 uni22E6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e7 uni22E7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e8 uni22E8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22e9 uni22E9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+22ea uni22EA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22eb uni22EB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ec uni22EC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ed uni22ED 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ef uni22EF 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+22f2 uni22F2 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f3 uni22F3 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f4 uni22F4 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f5 uni22F5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f6 uni22F6 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f7 uni22F7 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f8 uni22F8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22f9 uni22F9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22fa uni22FA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22fb uni22FB 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22fc uni22FC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22fd uni22FD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22fe uni22FE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+22ff uni22FF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2300 uni2300 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2301 uni2301 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2302 house 1.14 +U+2303 uni2303 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2304 uni2304 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2305 uni2305 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2306 uni2306 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2308 uni2308 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2309 uni2309 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+230a uni230A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+230b uni230B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+230c uni230C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+230d uni230D 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+230e uni230E 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+230f uni230F 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2310 revlogicalnot 1.14 +U+2311 uni2311 1.15 +U+2312 uni2312 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2313 uni2313 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2314 uni2314 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2315 uni2315 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2318 uni2318 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2319 uni2319 1.14 +U+231c uni231C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+231d uni231D 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+231e uni231E 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+231f uni231F 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2320 integraltp 2.3 +U+2321 integralbt 2.3 +U+2325 uni2325 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2326 uni2326 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2327 uni2327 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2328 uni2328 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2329 angleleft 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+232a angleright 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+232b uni232B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2335 uni2335 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2337 uni2337 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2338 uni2338 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2339 uni2339 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+233a uni233A 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+233b uni233B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+233c uni233C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+233d uni233D 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+233e uni233E 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2341 uni2341 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2342 uni2342 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2343 uni2343 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2344 uni2344 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2347 uni2347 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2348 uni2348 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2349 uni2349 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+234b uni234B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+234c uni234C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+234d uni234D 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2350 uni2350 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2352 uni2352 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2353 uni2353 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2354 uni2354 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2357 uni2357 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2358 uni2358 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2359 uni2359 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+235a uni235A 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+235b uni235B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+235c uni235C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+235e uni235E 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+235f uni235F 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2360 uni2360 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2363 uni2363 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2364 uni2364 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2365 uni2365 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2368 uni2368 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2369 uni2369 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+236b uni236B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+236c uni236C 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+236d uni236D 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+236e uni236E 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+236f uni236F 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2370 uni2370 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2373 uni2373 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2374 uni2374 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2375 uni2375 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2376 uni2376 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2377 uni2377 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2378 uni2378 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2379 uni2379 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+237a uni237A 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+237d uni237D 1.15 +U+2380 uni2380 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2381 uni2381 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2382 uni2382 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2383 uni2383 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2388 uni2388 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2389 uni2389 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+238a uni238A 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+238b uni238B 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+2395 uni2395 2.14 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+239b uni239B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+239c uni239C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+239d uni239D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+239e uni239E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+239f uni239F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a0 uni23A0 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a1 uni23A1 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a2 uni23A2 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a3 uni23A3 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a4 uni23A4 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a5 uni23A5 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a6 uni23A6 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a7 uni23A7 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a8 uni23A8 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23a9 uni23A9 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23aa uni23AA 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23ab uni23AB 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23ac uni23AC 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23ad uni23AD 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23ae uni23AE 2.3 +U+23ce uni23CE 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) +U+23cf uni23CF 2.3 +U+2422 uni2422 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2423 uni2423 1.6 +U+2460 uni2460 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2461 uni2461 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2462 uni2462 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2463 uni2463 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2464 uni2464 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2465 uni2465 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2466 uni2466 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2467 uni2467 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2468 uni2468 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2469 uni2469 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2500 SF100000 1.12 (Sans Mono, Sans Mono Oblique) +U+2501 uni2501 1.12 (Sans Mono, Sans Mono Oblique) +U+2502 SF110000 1.12 (Sans Mono, Sans Mono Oblique) +U+2503 uni2503 1.12 (Sans Mono, Sans Mono Oblique) +U+2504 uni2504 1.12 (Sans Mono, Sans Mono Oblique) +U+2505 uni2505 1.12 (Sans Mono, Sans Mono Oblique) +U+2506 uni2506 1.12 (Sans Mono, Sans Mono Oblique) +U+2507 uni2507 1.12 (Sans Mono, Sans Mono Oblique) +U+2508 uni2508 1.12 (Sans Mono, Sans Mono Oblique) +U+2509 uni2509 1.12 (Sans Mono, Sans Mono Oblique) +U+250a uni250A 1.12 (Sans Mono, Sans Mono Oblique) +U+250b uni250B 1.12 (Sans Mono, Sans Mono Oblique) +U+250c SF010000 1.12 (Sans Mono, Sans Mono Oblique) +U+250d uni250D 1.12 (Sans Mono, Sans Mono Oblique) +U+250e uni250E 1.12 (Sans Mono, Sans Mono Oblique) +U+250f uni250F 1.12 (Sans Mono, Sans Mono Oblique) +U+2510 SF030000 1.12 (Sans Mono, Sans Mono Oblique) +U+2511 uni2511 1.12 (Sans Mono, Sans Mono Oblique) +U+2512 uni2512 1.12 (Sans Mono, Sans Mono Oblique) +U+2513 uni2513 1.12 (Sans Mono, Sans Mono Oblique) +U+2514 SF020000 1.12 (Sans Mono, Sans Mono Oblique) +U+2515 uni2515 1.12 (Sans Mono, Sans Mono Oblique) +U+2516 uni2516 1.12 (Sans Mono, Sans Mono Oblique) +U+2517 uni2517 1.12 (Sans Mono, Sans Mono Oblique) +U+2518 SF040000 1.12 (Sans Mono, Sans Mono Oblique) +U+2519 uni2519 1.12 (Sans Mono, Sans Mono Oblique) +U+251a uni251A 1.12 (Sans Mono, Sans Mono Oblique) +U+251b uni251B 1.12 (Sans Mono, Sans Mono Oblique) +U+251c SF080000 1.12 (Sans Mono, Sans Mono Oblique) +U+251d uni251D 1.12 (Sans Mono, Sans Mono Oblique) +U+251e uni251E 1.12 (Sans Mono, Sans Mono Oblique) +U+251f uni251F 1.12 (Sans Mono, Sans Mono Oblique) +U+2520 uni2520 1.12 (Sans Mono, Sans Mono Oblique) +U+2521 uni2521 1.12 (Sans Mono, Sans Mono Oblique) +U+2522 uni2522 1.12 (Sans Mono, Sans Mono Oblique) +U+2523 uni2523 1.12 (Sans Mono, Sans Mono Oblique) +U+2524 SF090000 1.12 (Sans Mono, Sans Mono Oblique) +U+2525 uni2525 1.12 (Sans Mono, Sans Mono Oblique) +U+2526 uni2526 1.12 (Sans Mono, Sans Mono Oblique) +U+2527 uni2527 1.12 (Sans Mono, Sans Mono Oblique) +U+2528 uni2528 1.12 (Sans Mono, Sans Mono Oblique) +U+2529 uni2529 1.12 (Sans Mono, Sans Mono Oblique) +U+252a uni252A 1.12 (Sans Mono, Sans Mono Oblique) +U+252b uni252B 1.12 (Sans Mono, Sans Mono Oblique) +U+252c SF060000 1.12 (Sans Mono, Sans Mono Oblique) +U+252d uni252D 1.12 (Sans Mono, Sans Mono Oblique) +U+252e uni252E 1.12 (Sans Mono, Sans Mono Oblique) +U+252f uni252F 1.12 (Sans Mono, Sans Mono Oblique) +U+2530 uni2530 1.12 (Sans Mono, Sans Mono Oblique) +U+2531 uni2531 1.12 (Sans Mono, Sans Mono Oblique) +U+2532 uni2532 1.12 (Sans Mono, Sans Mono Oblique) +U+2533 uni2533 1.12 (Sans Mono, Sans Mono Oblique) +U+2534 SF070000 1.12 (Sans Mono, Sans Mono Oblique) +U+2535 uni2535 1.12 (Sans Mono, Sans Mono Oblique) +U+2536 uni2536 1.12 (Sans Mono, Sans Mono Oblique) +U+2537 uni2537 1.12 (Sans Mono, Sans Mono Oblique) +U+2538 uni2538 1.12 (Sans Mono, Sans Mono Oblique) +U+2539 uni2539 1.12 (Sans Mono, Sans Mono Oblique) +U+253a uni253A 1.12 (Sans Mono, Sans Mono Oblique) +U+253b uni253B 1.12 (Sans Mono, Sans Mono Oblique) +U+253c SF050000 1.12 (Sans Mono, Sans Mono Oblique) +U+253d uni253D 1.12 (Sans Mono, Sans Mono Oblique) +U+253e uni253E 1.12 (Sans Mono, Sans Mono Oblique) +U+253f uni253F 1.12 (Sans Mono, Sans Mono Oblique) +U+2540 uni2540 1.12 (Sans Mono, Sans Mono Oblique) +U+2541 uni2541 1.12 (Sans Mono, Sans Mono Oblique) +U+2542 uni2542 1.12 (Sans Mono, Sans Mono Oblique) +U+2543 uni2543 1.12 (Sans Mono, Sans Mono Oblique) +U+2544 uni2544 1.12 (Sans Mono, Sans Mono Oblique) +U+2545 uni2545 1.12 (Sans Mono, Sans Mono Oblique) +U+2546 uni2546 1.12 (Sans Mono, Sans Mono Oblique) +U+2547 uni2547 1.12 (Sans Mono, Sans Mono Oblique) +U+2548 uni2548 1.12 (Sans Mono, Sans Mono Oblique) +U+2549 uni2549 1.12 (Sans Mono, Sans Mono Oblique) +U+254a uni254A 1.12 (Sans Mono, Sans Mono Oblique) +U+254b uni254B 1.12 (Sans Mono, Sans Mono Oblique) +U+254c uni254C 1.12 (Sans Mono, Sans Mono Oblique) +U+254d uni254D 1.12 (Sans Mono, Sans Mono Oblique) +U+254e uni254E 1.12 (Sans Mono, Sans Mono Oblique) +U+254f uni254F 1.12 (Sans Mono, Sans Mono Oblique) +U+2550 SF430000 1.12 (Sans Mono, Sans Mono Oblique) +U+2551 SF240000 1.12 (Sans Mono, Sans Mono Oblique) +U+2552 SF510000 1.12 (Sans Mono, Sans Mono Oblique) +U+2553 SF520000 1.12 (Sans Mono, Sans Mono Oblique) +U+2554 SF390000 1.12 (Sans Mono, Sans Mono Oblique) +U+2555 SF220000 1.12 (Sans Mono, Sans Mono Oblique) +U+2556 SF210000 1.12 (Sans Mono, Sans Mono Oblique) +U+2557 SF250000 1.12 (Sans Mono, Sans Mono Oblique) +U+2558 SF500000 1.12 (Sans Mono, Sans Mono Oblique) +U+2559 SF490000 1.12 (Sans Mono, Sans Mono Oblique) +U+255a SF380000 1.12 (Sans Mono, Sans Mono Oblique) +U+255b SF280000 1.12 (Sans Mono, Sans Mono Oblique) +U+255c SF270000 1.12 (Sans Mono, Sans Mono Oblique) +U+255d SF260000 1.12 (Sans Mono, Sans Mono Oblique) +U+255e SF360000 1.12 (Sans Mono, Sans Mono Oblique) +U+255f SF370000 1.12 (Sans Mono, Sans Mono Oblique) +U+2560 SF420000 1.12 (Sans Mono, Sans Mono Oblique) +U+2561 SF190000 1.12 (Sans Mono, Sans Mono Oblique) +U+2562 SF200000 1.12 (Sans Mono, Sans Mono Oblique) +U+2563 SF230000 1.12 (Sans Mono, Sans Mono Oblique) +U+2564 SF470000 1.12 (Sans Mono, Sans Mono Oblique) +U+2565 SF480000 1.12 (Sans Mono, Sans Mono Oblique) +U+2566 SF410000 1.12 (Sans Mono, Sans Mono Oblique) +U+2567 SF450000 1.12 (Sans Mono, Sans Mono Oblique) +U+2568 SF460000 1.12 (Sans Mono, Sans Mono Oblique) +U+2569 SF400000 1.12 (Sans Mono, Sans Mono Oblique) +U+256a SF540000 1.12 (Sans Mono, Sans Mono Oblique) +U+256b SF530000 1.12 (Sans Mono, Sans Mono Oblique) +U+256c SF440000 1.12 (Sans Mono, Sans Mono Oblique) +U+256d uni256D 1.12 (Sans Mono, Sans Mono Oblique) +U+256e uni256E 1.12 (Sans Mono, Sans Mono Oblique) +U+256f uni256F 1.12 (Sans Mono, Sans Mono Oblique) +U+2570 uni2570 1.12 (Sans Mono, Sans Mono Oblique) +U+2571 uni2571 1.12 (Sans Mono, Sans Mono Oblique) +U+2572 uni2572 1.12 (Sans Mono, Sans Mono Oblique) +U+2573 uni2573 1.12 (Sans Mono, Sans Mono Oblique) +U+2574 uni2574 1.12 (Sans Mono, Sans Mono Oblique) +U+2575 uni2575 1.12 (Sans Mono, Sans Mono Oblique) +U+2576 uni2576 1.12 (Sans Mono, Sans Mono Oblique) +U+2577 uni2577 1.12 (Sans Mono, Sans Mono Oblique) +U+2578 uni2578 1.12 (Sans Mono, Sans Mono Oblique) +U+2579 uni2579 1.12 (Sans Mono, Sans Mono Oblique) +U+257a uni257A 1.12 (Sans Mono, Sans Mono Oblique) +U+257b uni257B 1.12 (Sans Mono, Sans Mono Oblique) +U+257c uni257C 1.12 (Sans Mono, Sans Mono Oblique) +U+257d uni257D 1.12 (Sans Mono, Sans Mono Oblique) +U+257e uni257E 1.12 (Sans Mono, Sans Mono Oblique) +U+257f uni257F 1.12 (Sans Mono, Sans Mono Oblique) +U+2580 upblock 1.14 +U+2581 uni2581 1.14 +U+2582 uni2582 1.14 +U+2583 uni2583 1.14 +U+2584 dnblock 1.14 +U+2585 uni2585 1.14 +U+2586 uni2586 1.14 +U+2587 uni2587 1.14 +U+2588 block 1.14 +U+2589 uni2589 1.14 +U+258a uni258A 1.14 +U+258b uni258B 1.14 +U+258c lfblock 1.14 +U+258d uni258D 1.14 +U+258e uni258E 1.14 +U+258f uni258F 1.14 +U+2590 rtblock 1.14 +U+2591 ltshade 1.15 +U+2592 shade 1.15 +U+2593 dkshade 1.15 +U+2594 uni2594 1.14 +U+2595 uni2595 1.14 +U+2596 uni2596 1.14 +U+2597 uni2597 1.14 +U+2598 uni2598 1.14 +U+2599 uni2599 1.14 +U+259a uni259A 1.14 +U+259b uni259B 1.14 +U+259c uni259C 1.14 +U+259d uni259D 1.14 +U+259e uni259E 1.14 +U+259f uni259F 1.14 +U+25a0 filledbox 2.3 +U+25a1 h32073 2.3 +U+25a2 uni25A2 2.3 +U+25a3 uni25A3 2.3 +U+25a4 uni25A4 2.3 +U+25a5 uni25A5 2.3 +U+25a6 uni25A6 2.3 +U+25a7 uni25A7 2.3 +U+25a8 uni25A8 2.3 +U+25a9 uni25A9 2.3 +U+25aa H18543 2.3 +U+25ab H18551 2.3 +U+25ac filledrect 2.3 +U+25ad uni25AD 2.3 +U+25ae uni25AE 2.3 +U+25af uni25AF 2.3 +U+25b0 uni25B0 2.3 +U+25b1 uni25B1 2.3 +U+25b2 triagup 2.3 +U+25b3 uni25B3 2.3 +U+25b4 uni25B4 2.3 +U+25b5 uni25B5 2.3 +U+25b6 uni25B6 2.3 +U+25b7 uni25B7 2.3 +U+25b8 uni25B8 2.3 +U+25b9 uni25B9 2.3 +U+25ba triagrt 2.3 +U+25bb uni25BB 2.3 +U+25bc triagdn 2.3 +U+25bd uni25BD 2.3 +U+25be uni25BE 2.3 +U+25bf uni25BF 2.3 +U+25c0 uni25C0 2.3 +U+25c1 uni25C1 2.3 +U+25c2 uni25C2 2.3 +U+25c3 uni25C3 2.3 +U+25c4 triaglf 2.3 +U+25c5 uni25C5 2.3 +U+25c6 uni25C6 2.3 +U+25c7 uni25C7 2.3 +U+25c8 uni25C8 2.3 +U+25c9 uni25C9 2.3 +U+25ca lozenge original +U+25cb circle 2.3 +U+25cc uni25CC 2.3 +U+25cd uni25CD 2.3 +U+25ce uni25CE 2.3 +U+25cf H18533 2.3 +U+25d0 uni25D0 2.3 +U+25d1 uni25D1 2.3 +U+25d2 uni25D2 2.3 +U+25d3 uni25D3 2.3 +U+25d4 uni25D4 2.3 +U+25d5 uni25D5 2.3 +U+25d6 uni25D6 2.3 +U+25d7 uni25D7 2.3 +U+25d8 invbullet 2.2 +U+25d9 invcircle 2.3 +U+25da uni25DA 2.3 +U+25db uni25DB 2.3 +U+25dc uni25DC 2.3 +U+25dd uni25DD 2.3 +U+25de uni25DE 2.3 +U+25df uni25DF 2.3 +U+25e0 uni25E0 2.3 +U+25e1 uni25E1 2.3 +U+25e2 uni25E2 2.3 +U+25e3 uni25E3 2.3 +U+25e4 uni25E4 2.3 +U+25e5 uni25E5 2.3 +U+25e6 openbullet 2.2 +U+25e7 uni25E7 2.3 +U+25e8 uni25E8 2.3 +U+25e9 uni25E9 2.3 +U+25ea uni25EA 2.3 +U+25eb uni25EB 2.3 +U+25ec uni25EC 2.3 +U+25ed uni25ED 2.3 +U+25ee uni25EE 2.3 +U+25ef uni25EF 2.3 +U+25f0 uni25F0 2.3 +U+25f1 uni25F1 2.3 +U+25f2 uni25F2 2.3 +U+25f3 uni25F3 2.3 +U+25f4 uni25F4 2.3 +U+25f5 uni25F5 2.3 +U+25f6 uni25F6 2.3 +U+25f7 uni25F7 2.3 +U+25f8 uni25F8 2.3 +U+25f9 uni25F9 2.3 +U+25fa uni25FA 2.3 +U+25fb uni25FB 2.3 +U+25fc uni25FC 2.3 +U+25fd uni25FD 2.3 +U+25fe uni25FE 2.3 +U+25ff uni25FF 2.3 +U+2600 uni2600 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2601 uni2601 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2602 uni2602 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2603 uni2603 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2604 uni2604 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2605 uni2605 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2606 uni2606 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2607 uni2607 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2608 uni2608 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2609 uni2609 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260a uni260A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260b uni260B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260c uni260C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260d uni260D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260e uni260E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+260f uni260F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2610 uni2610 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2611 uni2611 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2612 uni2612 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2613 uni2613 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2614 uni2614 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2615 uni2615 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2616 uni2616 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2617 uni2617 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2618 uni2618 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2619 uni2619 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261a uni261A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261b uni261B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261c uni261C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261d uni261D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261e uni261E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+261f uni261F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2620 uni2620 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2621 uni2621 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2622 uni2622 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2623 uni2623 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2624 uni2624 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2625 uni2625 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2626 uni2626 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2627 uni2627 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2628 uni2628 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2629 uni2629 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262a uni262A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262b uni262B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262c uni262C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262d uni262D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262e uni262E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+262f uni262F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2630 uni2630 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2631 uni2631 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2632 uni2632 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2633 uni2633 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2634 uni2634 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2635 uni2635 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2636 uni2636 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2637 uni2637 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2638 uni2638 1.15 +U+2639 uni2639 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+263a smileface 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+263b invsmileface 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+263c sun 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+263d uni263D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+263e uni263E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+263f uni263F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2640 female 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2641 uni2641 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2642 male 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2643 uni2643 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2644 uni2644 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2645 uni2645 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2646 uni2646 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2647 uni2647 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2648 uni2648 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2649 uni2649 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264a uni264A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264b uni264B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264c uni264C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264d uni264D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264e uni264E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+264f uni264F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2650 uni2650 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2651 uni2651 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2652 uni2652 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2653 uni2653 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2654 uni2654 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2655 uni2655 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2656 uni2656 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2657 uni2657 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2658 uni2658 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2659 uni2659 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265a uni265A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265b uni265B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265c uni265C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265d uni265D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265e uni265E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+265f uni265F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2660 spade 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2661 uni2661 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2662 uni2662 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2663 club 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2664 uni2664 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2665 heart 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2666 diamond 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2667 uni2667 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2668 uni2668 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2669 uni2669 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266a musicalnote 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266b musicalnotedbl 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266c uni266C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266d uni266D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266e uni266E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+266f uni266F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2670 uni2670 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2671 uni2671 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2672 uni2672 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2673 uni2673 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2674 uni2674 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2675 uni2675 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2676 uni2676 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2677 uni2677 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2678 uni2678 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2679 uni2679 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267a uni267A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267b uni267B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267c uni267C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267d uni267D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267e uni267E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+267f uni267F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2680 uni2680 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2681 uni2681 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2682 uni2682 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2683 uni2683 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2684 uni2684 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2685 uni2685 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold) +U+2686 uni2686 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2687 uni2687 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2688 uni2688 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2689 uni2689 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+268a uni268A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+268b uni268B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+268c uni268C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+268d uni268D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+268e uni268E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+268f uni268F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+2690 uni2690 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2691 uni2691 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2692 uni2692 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2693 uni2693 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2694 uni2694 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2695 uni2695 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2696 uni2696 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2697 uni2697 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2698 uni2698 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2699 uni2699 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+269a uni269A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+269b uni269B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+269c uni269C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+26a0 uni26A0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+26a1 uni26A1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+26a2 uni26A2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a3 uni26A3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a4 uni26A4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a5 uni26A5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a6 uni26A6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a7 uni26A7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a8 uni26A8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26a9 uni26A9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26aa uni26AA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26ab uni26AB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26ac uni26AC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26ad uni26AD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26ae uni26AE 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26af uni26AF 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+26b0 uni26B0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+26b1 uni26B1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+26b2 uni26B2 2.12 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2701 uni2701 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2702 uni2702 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2703 uni2703 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2704 uni2704 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2706 uni2706 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2707 uni2707 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2708 uni2708 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2709 uni2709 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+270c uni270C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+270d uni270D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+270e uni270E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+270f uni270F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2710 uni2710 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2711 uni2711 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2712 uni2712 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2713 uni2713 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2714 uni2714 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2715 uni2715 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2716 uni2716 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2717 uni2717 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2718 uni2718 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2719 uni2719 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271a uni271A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271b uni271B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271c uni271C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271d uni271D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271e uni271E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+271f uni271F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2720 uni2720 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2721 uni2721 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2722 uni2722 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2723 uni2723 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2724 uni2724 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2725 uni2725 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2726 uni2726 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2727 uni2727 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2729 uni2729 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272a uni272A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272b uni272B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272c uni272C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272d uni272D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272e uni272E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+272f uni272F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2730 uni2730 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2731 uni2731 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2732 uni2732 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2733 uni2733 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2734 uni2734 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2735 uni2735 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2736 uni2736 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2737 uni2737 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2738 uni2738 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2739 uni2739 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273a uni273A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273b uni273B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273c uni273C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273d uni273D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273e uni273E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+273f uni273F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2740 uni2740 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2741 uni2741 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2742 uni2742 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2743 uni2743 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2744 uni2744 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2745 uni2745 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2746 uni2746 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2747 uni2747 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2748 uni2748 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2749 uni2749 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+274a uni274A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+274b uni274B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+274d uni274D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+274f uni274F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2750 uni2750 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2751 uni2751 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2752 uni2752 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2756 uni2756 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2758 uni2758 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2759 uni2759 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+275a uni275A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+275b uni275B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+275c uni275C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+275d uni275D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+275e uni275E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2761 uni2761 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2762 uni2762 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2763 uni2763 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2764 uni2764 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2765 uni2765 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2766 uni2766 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2767 uni2767 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2768 uni2768 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2769 uni2769 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276a uni276A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276b uni276B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276c uni276C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276d uni276D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276e uni276E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+276f uni276F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2770 uni2770 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2771 uni2771 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2772 uni2772 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2773 uni2773 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2774 uni2774 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2775 uni2775 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) +U+2776 uni2776 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2777 uni2777 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2778 uni2778 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2779 uni2779 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277a uni277A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277b uni277B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277c uni277C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277d uni277D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277e uni277E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+277f uni277F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2780 uni2780 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2781 uni2781 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2782 uni2782 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2783 uni2783 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2784 uni2784 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2785 uni2785 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2786 uni2786 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2787 uni2787 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2788 uni2788 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2789 uni2789 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278a uni278A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278b uni278B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278c uni278C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278d uni278D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278e uni278E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+278f uni278F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2790 uni2790 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2791 uni2791 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2792 uni2792 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2793 uni2793 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2794 uni2794 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2798 uni2798 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+2799 uni2799 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279a uni279A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279b uni279B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279c uni279C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279d uni279D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279e uni279E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+279f uni279F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a0 uni27A0 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a1 uni27A1 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a2 uni27A2 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a3 uni27A3 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a4 uni27A4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a5 uni27A5 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a6 uni27A6 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a7 uni27A7 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a8 uni27A8 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27a9 uni27A9 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27aa uni27AA 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27ab uni27AB 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27ac uni27AC 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27ad uni27AD 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27ae uni27AE 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27af uni27AF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b1 uni27B1 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b2 uni27B2 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b3 uni27B3 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b4 uni27B4 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b5 uni27B5 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b6 uni27B6 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b7 uni27B7 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b8 uni27B8 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27b9 uni27B9 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27ba uni27BA 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27bb uni27BB 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27bc uni27BC 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27bd uni27BD 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27be uni27BE 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+27bf uni27BF 2.7 (Sans Mono Bold) +U+27e0 uni27E0 2.3 +U+27e6 uni27E6 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27e7 uni27E7 2.15 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27e8 uni27E8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+27e9 uni27E9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.13 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+27ea uni27EA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27eb uni27EB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f0 uni27F0 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f1 uni27F1 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f2 uni27F2 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f3 uni27F3 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f4 uni27F4 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f5 uni27F5 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f6 uni27F6 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f7 uni27F7 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f8 uni27F8 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27f9 uni27F9 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27fa uni27FA 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27fb uni27FB 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27fc uni27FC 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27fd uni27FD 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27fe uni27FE 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+27ff uni27FF 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2800 uni2800 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2801 uni2801 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2802 uni2802 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2803 uni2803 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2804 uni2804 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2805 uni2805 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2806 uni2806 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2807 uni2807 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2808 uni2808 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2809 uni2809 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280a uni280A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280b uni280B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280c uni280C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280d uni280D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280e uni280E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+280f uni280F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2810 uni2810 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2811 uni2811 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2812 uni2812 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2813 uni2813 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2814 uni2814 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2815 uni2815 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2816 uni2816 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2817 uni2817 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2818 uni2818 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2819 uni2819 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281a uni281A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281b uni281B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281c uni281C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281d uni281D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281e uni281E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+281f uni281F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2820 uni2820 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2821 uni2821 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2822 uni2822 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2823 uni2823 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2824 uni2824 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2825 uni2825 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2826 uni2826 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2827 uni2827 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2828 uni2828 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2829 uni2829 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282a uni282A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282b uni282B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282c uni282C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282d uni282D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282e uni282E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+282f uni282F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2830 uni2830 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2831 uni2831 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2832 uni2832 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2833 uni2833 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2834 uni2834 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2835 uni2835 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2836 uni2836 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2837 uni2837 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2838 uni2838 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2839 uni2839 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283a uni283A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283b uni283B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283c uni283C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283d uni283D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283e uni283E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+283f uni283F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2840 uni2840 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2841 uni2841 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2842 uni2842 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2843 uni2843 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2844 uni2844 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2845 uni2845 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2846 uni2846 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2847 uni2847 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2848 uni2848 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2849 uni2849 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284a uni284A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284b uni284B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284c uni284C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284d uni284D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284e uni284E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+284f uni284F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2850 uni2850 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2851 uni2851 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2852 uni2852 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2853 uni2853 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2854 uni2854 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2855 uni2855 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2856 uni2856 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2857 uni2857 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2858 uni2858 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2859 uni2859 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285a uni285A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285b uni285B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285c uni285C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285d uni285D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285e uni285E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+285f uni285F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2860 uni2860 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2861 uni2861 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2862 uni2862 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2863 uni2863 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2864 uni2864 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2865 uni2865 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2866 uni2866 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2867 uni2867 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2868 uni2868 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2869 uni2869 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286a uni286A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286b uni286B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286c uni286C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286d uni286D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286e uni286E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+286f uni286F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2870 uni2870 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2871 uni2871 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2872 uni2872 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2873 uni2873 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2874 uni2874 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2875 uni2875 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2876 uni2876 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2877 uni2877 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2878 uni2878 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2879 uni2879 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287a uni287A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287b uni287B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287c uni287C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287d uni287D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287e uni287E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+287f uni287F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2880 uni2880 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2881 uni2881 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2882 uni2882 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2883 uni2883 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2884 uni2884 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2885 uni2885 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2886 uni2886 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2887 uni2887 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2888 uni2888 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2889 uni2889 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288a uni288A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288b uni288B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288c uni288C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288d uni288D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288e uni288E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+288f uni288F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2890 uni2890 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2891 uni2891 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2892 uni2892 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2893 uni2893 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2894 uni2894 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2895 uni2895 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2896 uni2896 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2897 uni2897 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2898 uni2898 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2899 uni2899 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289a uni289A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289b uni289B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289c uni289C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289d uni289D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289e uni289E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+289f uni289F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a0 uni28A0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a1 uni28A1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a2 uni28A2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a3 uni28A3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a4 uni28A4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a5 uni28A5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a6 uni28A6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a7 uni28A7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a8 uni28A8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28a9 uni28A9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28aa uni28AA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ab uni28AB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ac uni28AC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ad uni28AD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ae uni28AE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28af uni28AF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b0 uni28B0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b1 uni28B1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b2 uni28B2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b3 uni28B3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b4 uni28B4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b5 uni28B5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b6 uni28B6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b7 uni28B7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b8 uni28B8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28b9 uni28B9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ba uni28BA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28bb uni28BB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28bc uni28BC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28bd uni28BD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28be uni28BE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28bf uni28BF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c0 uni28C0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c1 uni28C1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c2 uni28C2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c3 uni28C3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c4 uni28C4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c5 uni28C5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c6 uni28C6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c7 uni28C7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c8 uni28C8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28c9 uni28C9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ca uni28CA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28cb uni28CB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28cc uni28CC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28cd uni28CD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ce uni28CE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28cf uni28CF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d0 uni28D0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d1 uni28D1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d2 uni28D2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d3 uni28D3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d4 uni28D4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d5 uni28D5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d6 uni28D6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d7 uni28D7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d8 uni28D8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28d9 uni28D9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28da uni28DA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28db uni28DB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28dc uni28DC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28dd uni28DD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28de uni28DE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28df uni28DF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e0 uni28E0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e1 uni28E1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e2 uni28E2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e3 uni28E3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e4 uni28E4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e5 uni28E5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e6 uni28E6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e7 uni28E7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e8 uni28E8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28e9 uni28E9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ea uni28EA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28eb uni28EB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ec uni28EC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ed uni28ED 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ee uni28EE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ef uni28EF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f0 uni28F0 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f1 uni28F1 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f2 uni28F2 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f3 uni28F3 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f4 uni28F4 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f5 uni28F5 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f6 uni28F6 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f7 uni28F7 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f8 uni28F8 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28f9 uni28F9 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28fa uni28FA 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28fb uni28FB 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28fc uni28FC 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28fd uni28FD 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28fe uni28FE 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+28ff uni28FF 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2906 uni2906 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2907 uni2907 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+290a uni290A 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+290b uni290B 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2940 uni2940 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2941 uni2941 2.13 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29ce uni29CE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29cf uni29CF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d0 uni29D0 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d1 uni29D1 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d2 uni29D2 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d3 uni29D3 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d4 uni29D4 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29d5 uni29D5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+29eb uni29EB 2.2 +U+2a00 uni2A00 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a01 uni2A01 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a02 uni2A02 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a0c uni2A0C 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2a0d uni2A0D 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2a0e uni2A0E 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2a0f uni2A0F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a10 uni2A10 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a11 uni2A11 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a12 uni2A12 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a13 uni2A13 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a14 uni2A14 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a15 uni2A15 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a16 uni2A16 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a17 uni2A17 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a18 uni2A18 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a19 uni2A19 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a1a uni2A1A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a1b uni2A1B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a1c uni2A1C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a7d uni2A7D 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a7e uni2A7E 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a7f uni2A7F 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a80 uni2A80 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a81 uni2A81 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a82 uni2A82 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a83 uni2A83 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a84 uni2A84 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a85 uni2A85 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a86 uni2A86 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a87 uni2A87 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a88 uni2A88 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a89 uni2A89 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8a uni2A8A 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8b uni2A8B 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8c uni2A8C 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8d uni2A8D 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8e uni2A8E 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a8f uni2A8F 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a90 uni2A90 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a91 uni2A91 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a92 uni2A92 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a93 uni2A93 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a94 uni2A94 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a95 uni2A95 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a96 uni2A96 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a97 uni2A97 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a98 uni2A98 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a99 uni2A99 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9a uni2A9A 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9b uni2A9B 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9c uni2A9C 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9d uni2A9D 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9e uni2A9E 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2a9f uni2A9F 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2aa0 uni2AA0 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2aae uni2AAE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2aaf uni2AAF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab0 uni2AB0 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab1 uni2AB1 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab2 uni2AB2 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab3 uni2AB3 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab4 uni2AB4 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab5 uni2AB5 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab6 uni2AB6 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab7 uni2AB7 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab8 uni2AB8 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2ab9 uni2AB9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2aba uni2ABA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2af9 uni2AF9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2afa uni2AFA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b00 uni2B00 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b01 uni2B01 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b02 uni2B02 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b03 uni2B03 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b04 uni2B04 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b05 uni2B05 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b06 uni2B06 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b07 uni2B07 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b08 uni2B08 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b09 uni2B09 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0a uni2B0A 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0b uni2B0B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0c uni2B0C 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0d uni2B0D 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0e uni2B0E 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b0f uni2B0F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b10 uni2B10 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b11 uni2B11 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b12 uni2B12 2.3 +U+2b13 uni2B13 2.3 +U+2b14 uni2B14 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b15 uni2B15 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b16 uni2B16 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b17 uni2B17 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b18 uni2B18 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b19 uni2B19 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b1a uni2B1A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+2b20 uni2B20 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b21 uni2B21 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b22 uni2B22 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2b23 uni2B23 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c60 uni2C60 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c61 uni2C61 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c62 uni2C62 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c63 uni2C63 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c64 uni2C64 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c65 uni2C65 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c66 uni2C66 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c67 uni2C67 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c68 uni2C68 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c69 uni2C69 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c6a uni2C6A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c6b uni2C6B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c6c uni2C6C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c74 uni2C74 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+2c75 uni2C75 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c76 uni2C76 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c77 uni2C77 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e000 uniE000 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e001 uniE001 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e002 uniE002 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e003 uniE003 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e004 uniE004 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e005 uniE005 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e006 uniE006 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e007 uniE007 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e008 uniE008 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+e009 uniE009 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00a uniE00A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00b uniE00B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00c uniE00C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00d uniE00D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00e uniE00E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e00f uniE00F 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e010 uniE010 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e011 uniE011 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e012 uniE012 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e013 uniE013 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e014 uniE014 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) +U+e015 uniE015 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e016 uniE016 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e017 uniE017 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e018 uniE018 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e019 uniE019 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e01a uniE01A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e01b uniE01B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e01c uniE01C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+e01d uniE01D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f000 uniF000 2.10 (Sans) 2.11 (Sans Condensed) +U+f001 uniF001 2.10 (Sans) 2.11 (Sans Condensed) +U+f208 uniF208 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f20a uniF20A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f215 uniF215 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f216 uniF216 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f217 uniF217 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f21a uniF21A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f21b uniF21B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f25f uniF25F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f5c5 afii10064 2.9 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+f6c4 afii10063 2.10 (Serif Bold Oblique, Serif Oblique) 2.11 (Serif Condensed Bold Oblique, Serif Condensed Oblique) +U+f6c5 afii10064 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.9 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Oblique) +U+f6c6 afii10192 2.5 (Serif Bold Oblique, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+f6c7 afii10831 2.11 (Serif Bold Oblique, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+f6c8 afii10832 2.11 (Serif Bold Oblique, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+f6d1 cyrBreve 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+f6d4 cyrbreve 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb00 uniFB00 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) 2.8 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb01 fi original +U+fb02 fl original +U+fb03 uniFB03 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) 2.8 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb04 uniFB04 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) 2.8 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb05 uniFB05 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb06 uniFB06 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fb13 uniFB13 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb14 uniFB14 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb15 uniFB15 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb16 uniFB16 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb17 uniFB17 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb1d uniFB1D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb1f uniFB1F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb20 uniFB20 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb29 uniFB29 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) 2.11 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique) +U+fb2a uniFB2A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb2b uniFB2B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb2c uniFB2C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb2d uniFB2D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb2e uniFB2E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb2f uniFB2F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb30 uniFB30 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb31 uniFB31 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb32 uniFB32 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb33 uniFB33 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb34 uniFB34 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb35 uniFB35 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb36 uniFB36 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb37 uniFB37 2.11 (Sans Condensed Oblique, Sans Oblique) +U+fb38 uniFB38 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb39 uniFB39 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb3a uniFB3A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb3b uniFB3B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb3c uniFB3C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb3e uniFB3E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb40 uniFB40 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb41 uniFB41 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb43 uniFB43 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb44 uniFB44 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb46 uniFB46 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb47 uniFB47 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb48 uniFB48 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb49 uniFB49 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb4a uniFB4A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb4b uniFB4B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb4c uniFB4C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb4d uniFB4D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb4e uniFB4E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb52 uniFB52 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb53 uniFB53 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb54 uniFB54 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb55 uniFB55 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb56 uniFB56 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb57 uniFB57 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb58 uniFB58 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb59 uniFB59 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5a uniFB5A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5b uniFB5B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5c uniFB5C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5d uniFB5D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5e uniFB5E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb5f uniFB5F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb60 uniFB60 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb61 uniFB61 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb62 uniFB62 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb63 uniFB63 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb64 uniFB64 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb65 uniFB65 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb66 uniFB66 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb67 uniFB67 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb68 uniFB68 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb69 uniFB69 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6a uniFB6A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6b uniFB6B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6c uniFB6C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6d uniFB6D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6e uniFB6E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb6f uniFB6F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb70 uniFB70 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb71 uniFB71 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb72 uniFB72 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb73 uniFB73 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb74 uniFB74 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb75 uniFB75 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb76 uniFB76 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb77 uniFB77 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb78 uniFB78 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb79 uniFB79 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7a uniFB7A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7b uniFB7B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7c uniFB7C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7d uniFB7D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7e uniFB7E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb7f uniFB7F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb80 uniFB80 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb81 uniFB81 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8a uniFB8A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8b uniFB8B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8c uniFB8C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8d uniFB8D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8e uniFB8E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb8f uniFB8F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb90 uniFB90 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb91 uniFB91 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb92 uniFB92 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb93 uniFB93 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb94 uniFB94 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb95 uniFB95 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb9e uniFB9E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fb9f uniFB9F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbd9 uniFBD9 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbda uniFBDA 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbe8 uniFBE8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbe9 uniFBE9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbfc uniFBFC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbfd uniFBFD 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbfe uniFBFE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fbff uniFBFF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe00 uniFE00 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe01 uniFE01 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe02 uniFE02 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe03 uniFE03 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe04 uniFE04 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe05 uniFE05 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe06 uniFE06 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe07 uniFE07 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe08 uniFE08 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe09 uniFE09 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0a uniFE0A 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0b uniFE0B 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0c uniFE0C 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0d uniFE0D 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0e uniFE0E 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe0f uniFE0F 2.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+fe70 uniFE70 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe71 uniFE71 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe72 uniFE72 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe73 uniFE73 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe74 uniFE74 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe76 uniFE76 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe77 uniFE77 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe78 uniFE78 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe79 uniFE79 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7a uniFE7A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7b uniFE7B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7c uniFE7C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7d uniFE7D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7e uniFE7E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe7f uniFE7F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe80 uniFE80 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe81 uniFE81 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe82 uniFE82 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe83 uniFE83 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe84 uniFE84 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe85 uniFE85 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe86 uniFE86 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe87 uniFE87 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe88 uniFE88 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe89 uniFE89 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8a uniFE8A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8b uniFE8B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8c uniFE8C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8d uniFE8D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8e uniFE8E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe8f uniFE8F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe90 uniFE90 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe91 uniFE91 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe92 uniFE92 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe93 uniFE93 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe94 uniFE94 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe95 uniFE95 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe96 uniFE96 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe97 uniFE97 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe98 uniFE98 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe99 uniFE99 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9a uniFE9A 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9b uniFE9B 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9c uniFE9C 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9d uniFE9D 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9e uniFE9E 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fe9f uniFE9F 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea0 uniFEA0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea1 uniFEA1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea2 uniFEA2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea3 uniFEA3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea4 uniFEA4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea5 uniFEA5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea6 uniFEA6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea7 uniFEA7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea8 uniFEA8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fea9 uniFEA9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feaa uniFEAA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feab uniFEAB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feac uniFEAC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fead uniFEAD 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feae uniFEAE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feaf uniFEAF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb0 uniFEB0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb1 uniFEB1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb2 uniFEB2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb3 uniFEB3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb4 uniFEB4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb5 uniFEB5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb6 uniFEB6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb7 uniFEB7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb8 uniFEB8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feb9 uniFEB9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feba uniFEBA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+febb uniFEBB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+febc uniFEBC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+febd uniFEBD 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+febe uniFEBE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+febf uniFEBF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec0 uniFEC0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec1 uniFEC1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec2 uniFEC2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec3 uniFEC3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec4 uniFEC4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec5 uniFEC5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec6 uniFEC6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec7 uniFEC7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec8 uniFEC8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fec9 uniFEC9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feca uniFECA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fecb uniFECB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fecc uniFECC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fecd uniFECD 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fece uniFECE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fecf uniFECF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed0 uniFED0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed1 uniFED1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed2 uniFED2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed3 uniFED3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed4 uniFED4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed5 uniFED5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed6 uniFED6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed7 uniFED7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed8 uniFED8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fed9 uniFED9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feda uniFEDA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fedb uniFEDB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fedc uniFEDC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fedd uniFEDD 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fede uniFEDE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fedf uniFEDF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee0 uniFEE0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee1 uniFEE1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee2 uniFEE2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee3 uniFEE3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee4 uniFEE4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee5 uniFEE5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee6 uniFEE6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee7 uniFEE7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee8 uniFEE8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fee9 uniFEE9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feea uniFEEA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feeb uniFEEB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feec uniFEEC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feed uniFEED 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feee uniFEEE 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feef uniFEEF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef0 uniFEF0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef1 uniFEF1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef2 uniFEF2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef3 uniFEF3 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef4 uniFEF4 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef5 uniFEF5 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef6 uniFEF6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef7 uniFEF7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef8 uniFEF8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fef9 uniFEF9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fefa uniFEFA 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fefb uniFEFB 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fefc uniFEFC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+feff uniFEFF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+fffd uniFFFD 1.12 diff --git a/lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/unicover.txt b/lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/unicover.txt new file mode 100644 index 000000000..8c2d5c94d --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/dejavu-ttf-2.15/unicover.txt @@ -0,0 +1,160 @@ +This is the Unicode coverage file for DejaVu fonts +($Id: unicover.txt 1586 2007-02-18 16:07:32Z ben_laenen $) + +Control and similar characters are discounted from totals. + + Sans Serif Sans Mono +U+0000 Basic Latin 100% (95/95) 100% (95/95) 100% (95/95) +U+0080 Latin-1 Supplement 100% (96/96) 100% (96/96) 100% (96/96) +U+0100 Latin Extended-A 100% (128/128) 100% (128/128) 100% (128/128) +U+0180 Latin Extended-B 100% (208/208) 90% (188/208) 78% (163/208) +U+0250 IPA Extensions 100% (96/96) 100% (96/96) 100% (96/96) +U+02b0 Spacing Modifier Letters 78% (63/80) 56% (45/80) 57% (46/80) +U+0300 Combining Diacritical Marks 82% (92/112) 60% (68/112) 59% (67/112) +U+0370 Greek and Coptic 100% (127/127) 86% (110/127) 86% (110/127) +U+0400 Cyrillic 100% (255/255) 75% (192/255) 66% (170/255) +U+0500 Cyrillic Supplement 100% (20/20) (0/20) (0/20) +U+0530 Armenian 100% (86/86) (0/86) (0/86) +U+0590 Hebrew 57% (50/87) (0/87) (0/87) +U+0600 Arabic 47% (111/235) (0/235) (0/235) +U+0700 Syriac (0/77) (0/77) (0/77) +U+0750 Arabic Supplement (0/30) (0/30) (0/30) +U+0780 Thaana (0/50) (0/50) (0/50) +U+07c0 NKo (0/59) (0/59) (0/59) +U+0900 Devanagari (0/111) (0/111) (0/111) +U+0980 Bengali (0/91) (0/91) (0/91) +U+0a00 Gurmukhi (0/77) (0/77) (0/77) +U+0a80 Gujarati (0/83) (0/83) (0/83) +U+0b00 Oriya (0/81) (0/81) (0/81) +U+0b80 Tamil (0/71) (0/71) (0/71) +U+0c00 Telugu (0/80) (0/80) (0/80) +U+0c80 Kannada (0/86) (0/86) (0/86) +U+0d00 Malayalam (0/78) (0/78) (0/78) +U+0d80 Sinhala (0/80) (0/80) (0/80) +U+0e00 Thai 1% (1/87) (0/87) (0/87) +U+0e80 Lao 84% (55/65) (0/65) 43% (28/65) +U+0f00 Tibetan (0/195) (0/195) (0/195) +U+1000 Myanmar (0/78) (0/78) (0/78) +U+10a0 Georgian (0/83) (0/83) (0/83) +U+1100 Hangul Jamo (0/240) (0/240) (0/240) +U+1200 Ethiopic (0/356) (0/356) (0/356) +U+1380 Ethiopic Supplement (0/26) (0/26) (0/26) +U+13a0 Cherokee (0/85) (0/85) (0/85) +U+1400 Unified Canadian Aboriginal Syllabics 64% (404/630) (0/630) (0/630) +U+1680 Ogham (0/29) (0/29) (0/29) +U+16a0 Runic (0/81) (0/81) (0/81) +U+1700 Tagalog (0/20) (0/20) (0/20) +U+1720 Hanunoo (0/23) (0/23) (0/23) +U+1740 Buhid (0/20) (0/20) (0/20) +U+1760 Tagbanwa (0/18) (0/18) (0/18) +U+1780 Khmer (0/114) (0/114) (0/114) +U+1800 Mongolian (0/155) (0/155) (0/155) +U+1900 Limbu (0/66) (0/66) (0/66) +U+1950 Tai Le (0/35) (0/35) (0/35) +U+1980 New Tai Lue (0/80) (0/80) (0/80) +U+19e0 Khmer Symbols (0/32) (0/32) (0/32) +U+1a00 Buginese (0/30) (0/30) (0/30) +U+1b00 Balinese (0/121) (0/121) (0/121) +U+1d00 Phonetic Extensions 82% (105/128) 28% (36/128) 28% (36/128) +U+1d80 Phonetic Extensions Supplement 59% (38/64) 57% (37/64) 57% (37/64) +U+1dc0 Combining Diacritical Marks Supplement 46% (6/13) (0/13) (0/13) +U+1e00 Latin Extended Additional 100% (246/246) 77% (190/246) 54% (134/246) +U+1f00 Greek Extended 100% (233/233) 100% (233/233) 100% (233/233) +U+2000 General Punctuation 98% (104/106) 61% (65/106) 42% (45/106) +U+2070 Superscripts and Subscripts 100% (34/34) 52% (18/34) 52% (18/34) +U+20a0 Currency Symbols 100% (22/22) 27% (6/22) 22% (5/22) +U+20d0 Combining Diacritical Marks for Symbols 12% (4/32) (0/32) (0/32) +U+2100 Letterlike Symbols 94% (75/79) 7% (6/79) 7% (6/79) +U+2150 Number Forms 100% (50/50) 26% (13/50) 26% (13/50) +U+2190 Arrows 100% (112/112) 3% (4/112) 100% (112/112) +U+2200 Mathematical Operators 93% (239/256) 10% (27/256) 56% (145/256) +U+2300 Miscellaneous Technical 15% (37/232) 6% (16/232) 50% (117/232) +U+2400 Control Pictures 5% (2/39) 2% (1/39) 2% (1/39) +U+2440 Optical Character Recognition (0/11) (0/11) (0/11) +U+2460 Enclosed Alphanumerics 6% (10/160) (0/160) (0/160) +U+2500 Box Drawing (0/128) (0/128) 100% (128/128) +U+2580 Block Elements 100% (32/32) 100% (32/32) 100% (32/32) +U+25a0 Geometric Shapes 100% (96/96) 100% (96/96) 100% (96/96) +U+2600 Miscellaneous Symbols 100% (176/176) 17% (30/176) 84% (149/176) +U+2700 Dingbats 100% (174/174) (0/174) 82% (144/174) +U+27c0 Miscellaneous Mathematical Symbols-A 17% (7/39) 7% (3/39) 7% (3/39) +U+27f0 Supplemental Arrows-A 100% (16/16) (0/16) (0/16) +U+2800 Braille Patterns 100% (256/256) (0/256) (0/256) +U+2900 Supplemental Arrows-B 4% (6/128) (0/128) (0/128) +U+2980 Miscellaneous Mathematical Symbols-B 7% (9/128) 0% (1/128) 0% (1/128) +U+2a00 Supplemental Mathematical Operators 27% (71/256) 1% (3/256) (0/256) +U+2b00 Miscellaneous Symbols and Arrows 100% (31/31) 29% (9/31) 29% (9/31) +U+2c00 Glagolitic (0/94) (0/94) (0/94) +U+2c60 Latin Extended-C 100% (17/17) (0/17) (0/17) +U+2c80 Coptic (0/114) (0/114) (0/114) +U+2d00 Georgian Supplement (0/38) (0/38) (0/38) +U+2d30 Tifinagh (0/55) (0/55) (0/55) +U+2d80 Ethiopic Extended (0/79) (0/79) (0/79) +U+2e00 Supplemental Punctuation (0/26) (0/26) (0/26) +U+2e80 CJK Radicals Supplement (0/115) (0/115) (0/115) +U+2f00 Kangxi Radicals (0/214) (0/214) (0/214) +U+2ff0 Ideographic Description Characters (0/12) (0/12) (0/12) +U+3000 CJK Symbols and Punctuation (0/64) (0/64) (0/64) +U+3040 Hiragana (0/93) (0/93) (0/93) +U+30a0 Katakana (0/96) (0/96) (0/96) +U+3100 Bopomofo (0/40) (0/40) (0/40) +U+3130 Hangul Compatibility Jamo (0/94) (0/94) (0/94) +U+3190 Kanbun (0/16) (0/16) (0/16) +U+31a0 Bopomofo Extended (0/24) (0/24) (0/24) +U+31c0 CJK Strokes (0/16) (0/16) (0/16) +U+31f0 Katakana Phonetic Extensions (0/16) (0/16) (0/16) +U+3200 Enclosed CJK Letters and Months (0/242) (0/242) (0/242) +U+3300 CJK Compatibility (0/256) (0/256) (0/256) +U+3400 CJK Unified Ideographs Extension A (0/0) (0/0) (0/0) +U+4dc0 Yijing Hexagram Symbols (0/64) (0/64) (0/64) +U+4e00 CJK Unified Ideographs (0/0) (0/0) (0/0) +U+a000 Yi Syllables (0/1165) (0/1165) (0/1165) +U+a490 Yi Radicals (0/55) (0/55) (0/55) +U+a700 Modifier Tone Letters (0/27) (0/27) (0/27) +U+a720 Latin Extended-D (0/2) (0/2) (0/2) +U+a800 Syloti Nagri (0/44) (0/44) (0/44) +U+a840 Phags-pa (0/56) (0/56) (0/56) +U+ac00 Hangul Syllables (0/0) (0/0) (0/0) +U+d800 High Surrogates (0/0) (0/0) (0/0) +U+db80 High Private Use Surrogates (0/0) (0/0) (0/0) +U+dc00 Low Surrogates (0/0) (0/0) (0/0) +U+e000 Private Use Area (0/0) (0/0) (0/0) +U+f900 CJK Compatibility Ideographs (0/467) (0/467) (0/467) +U+fb00 Alphabetic Presentation Forms 82% (48/58) 12% (7/58) 3% (2/58) +U+fb50 Arabic Presentation Forms-A 11% (70/595) (0/595) (0/595) +U+fe00 Variation Selectors 100% (16/16) 100% (16/16) (0/16) +U+fe10 Vertical Forms (0/10) (0/10) (0/10) +U+fe20 Combining Half Marks (0/4) (0/4) (0/4) +U+fe30 CJK Compatibility Forms (0/32) (0/32) (0/32) +U+fe50 Small Form Variants (0/26) (0/26) (0/26) +U+fe70 Arabic Presentation Forms-B 100% (141/141) (0/141) (0/141) +U+ff00 Halfwidth and Fullwidth Forms (0/225) (0/225) (0/225) +U+fff0 Specials 20% (1/5) 20% (1/5) 20% (1/5) +U+10000 Linear B Syllabary (0/88) (0/88) (0/88) +U+10080 Linear B Ideograms (0/123) (0/123) (0/123) +U+10100 Aegean Numbers (0/57) (0/57) (0/57) +U+10140 Ancient Greek Numbers (0/75) (0/75) (0/75) +U+10300 Old Italic (0/35) (0/35) (0/35) +U+10330 Gothic (0/27) (0/27) (0/27) +U+10380 Ugaritic (0/31) (0/31) (0/31) +U+103a0 Old Persian (0/50) (0/50) (0/50) +U+10400 Deseret (0/80) (0/80) (0/80) +U+10450 Shavian (0/48) (0/48) (0/48) +U+10480 Osmanya (0/40) (0/40) (0/40) +U+10800 Cypriot Syllabary (0/55) (0/55) (0/55) +U+10900 Phoenician (0/27) (0/27) (0/27) +U+10a00 Kharoshthi (0/65) (0/65) (0/65) +U+12000 Cuneiform (0/879) (0/879) (0/879) +U+12400 Cuneiform Numbers and Punctuation (0/103) (0/103) (0/103) +U+1d000 Byzantine Musical Symbols (0/246) (0/246) (0/246) +U+1d100 Musical Symbols (0/219) (0/219) (0/219) +U+1d200 Ancient Greek Musical Notation (0/70) (0/70) (0/70) +U+1d300 Tai Xuan Jing Symbols (0/87) (0/87) (0/87) +U+1d360 Counting Rod Numerals (0/18) (0/18) (0/18) +U+1d400 Mathematical Alphanumeric Symbols (0/996) (0/996) (0/996) +U+20000 CJK Unified Ideographs Extension B (0/0) (0/0) (0/0) +U+2f800 CJK Compatibility Ideographs Supplement (0/542) (0/542) (0/542) +U+e0000 Tags (0/98) (0/98) (0/98) +U+e0100 Variation Selectors Supplement (0/240) (0/240) (0/240) +U+f0000 Supplementary Private Use Area-A (0/0) (0/0) (0/0) +U+100000 Supplementary Private Use Area-B (0/0) (0/0) (0/0) diff --git a/lib/plugins/rfpdf/lib/fonts/dejavusans.rb b/lib/plugins/rfpdf/lib/fonts/dejavusans.rb new file mode 100644 index 000000000..660c4a8fe --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/dejavusans.rb @@ -0,0 +1,287 @@ +TCPDFFontDescriptor.define('dejavusans') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='DejaVuSans'; + font[:desc]={'Ascent'=>928,'Descent'=>-236,'CapHeight'=>928,'Flags'=>32,'FontBBox'=>'[-1021 -356 1681 1068]','ItalicAngle'=>0,'StemV'=>70,'MissingWidth'=>600}; + font[:up]=-42; + font[:ut]=44; + font[:cw]={ + 0=>600, 32=>318, 33=>401, 34=>460, 35=>838, 36=>636, 37=>950, 38=>780, 39=>275, 40=>390, 41=>390, 42=>500, 43=>838, 44=>318, 45=>361, 46=>318, + 47=>337, 48=>636, 49=>636, 50=>636, 51=>636, 52=>636, 53=>636, 54=>636, 55=>636, 56=>636, 57=>636, 58=>337, 59=>337, 60=>838, 61=>838, 62=>838, + 63=>531, 64=>1000, 65=>684, 66=>686, 67=>698, 68=>770, 69=>632, 70=>575, 71=>775, 72=>752, 73=>295, 74=>295, 75=>656, 76=>557, 77=>863, 78=>748, + 79=>787, 80=>603, 81=>787, 82=>695, 83=>635, 84=>611, 85=>732, 86=>684, 87=>989, 88=>685, 89=>611, 90=>685, 91=>390, 92=>337, 93=>390, 94=>838, + 95=>500, 96=>500, 97=>613, 98=>635, 99=>550, 100=>635, 101=>615, 102=>352, 103=>635, 104=>634, 105=>278, 106=>278, 107=>579, 108=>278, 109=>974, 110=>634, + 111=>612, 112=>635, 113=>635, 114=>411, 115=>521, 116=>392, 117=>634, 118=>592, 119=>818, 120=>592, 121=>592, 122=>525, 123=>636, 124=>337, 125=>636, 126=>838, + 8364=>636, 1027=>610, 8218=>318, 402=>352, 8222=>518, 8230=>1000, 8224=>500, 8225=>500, 710=>500, 8240=>1342, 352=>635, 8249=>400, 338=>1070, 1036=>710, 381=>685, 1039=>752, + 8216=>318, 8217=>318, 8220=>518, 8221=>518, 8226=>590, 8211=>500, 8212=>1000, 732=>500, 8482=>1000, 353=>521, 8250=>400, 339=>1023, 1116=>604, 382=>525, 376=>611, 160=>318, + 161=>401, 162=>636, 163=>636, 164=>636, 165=>636, 166=>337, 167=>500, 168=>500, 169=>1000, 170=>471, 171=>612, 172=>838, 173=>361, 174=>1000, 175=>500, 176=>500, + 177=>838, 178=>401, 179=>401, 180=>500, 181=>636, 182=>636, 183=>318, 184=>500, 185=>401, 186=>471, 187=>612, 188=>969, 189=>969, 190=>969, 191=>531, 192=>684, + 193=>684, 194=>684, 195=>684, 196=>684, 197=>684, 198=>974, 199=>698, 200=>632, 201=>632, 202=>632, 203=>632, 204=>295, 205=>295, 206=>295, 207=>295, 208=>775, + 209=>748, 210=>787, 211=>787, 212=>787, 213=>787, 214=>787, 215=>838, 216=>787, 217=>732, 218=>732, 219=>732, 220=>732, 221=>611, 222=>605, 223=>630, 224=>613, + 225=>613, 226=>613, 227=>613, 228=>613, 229=>613, 230=>982, 231=>550, 232=>615, 233=>615, 234=>615, 235=>615, 236=>278, 237=>278, 238=>278, 239=>278, 240=>612, + 241=>634, 242=>612, 243=>612, 244=>612, 245=>612, 246=>612, 247=>838, 248=>612, 249=>634, 250=>634, 251=>634, 252=>634, 253=>592, 254=>635, 255=>592, 256=>684, + 257=>613, 258=>684, 259=>613, 260=>684, 261=>613, 262=>698, 263=>550, 264=>698, 265=>550, 266=>698, 267=>550, 268=>698, 269=>550, 270=>770, 271=>635, 272=>775, + 273=>635, 274=>632, 275=>615, 276=>632, 277=>615, 278=>632, 279=>615, 280=>632, 281=>615, 282=>632, 283=>615, 284=>775, 285=>635, 286=>775, 287=>635, 288=>775, + 289=>635, 290=>775, 291=>635, 292=>752, 293=>634, 294=>916, 295=>695, 296=>295, 297=>278, 298=>295, 299=>278, 300=>295, 301=>278, 302=>295, 303=>278, 304=>295, + 305=>278, 306=>590, 307=>556, 308=>295, 309=>278, 310=>656, 311=>579, 312=>579, 313=>557, 314=>293, 315=>557, 316=>278, 317=>557, 318=>375, 319=>557, 320=>342, + 321=>562, 322=>284, 323=>748, 324=>634, 325=>748, 326=>634, 327=>748, 328=>634, 329=>813, 330=>748, 331=>634, 332=>787, 333=>612, 334=>787, 335=>612, 336=>787, + 337=>612, 340=>695, 341=>411, 342=>695, 343=>411, 344=>695, 345=>411, 346=>635, 347=>521, 348=>635, 349=>521, 350=>635, 351=>521, 354=>611, 355=>392, 356=>611, + 357=>392, 358=>611, 359=>392, 360=>732, 361=>634, 362=>732, 363=>634, 364=>732, 365=>634, 366=>732, 367=>634, 368=>732, 369=>634, 370=>732, 371=>634, 372=>989, + 373=>818, 374=>611, 375=>592, 377=>685, 378=>525, 379=>685, 380=>525, 383=>352, 384=>635, 385=>735, 386=>686, 387=>635, 388=>686, 389=>635, 390=>703, 391=>698, + 392=>550, 393=>775, 394=>819, 395=>686, 396=>635, 397=>612, 398=>632, 399=>787, 400=>614, 401=>575, 403=>775, 404=>687, 405=>984, 406=>354, 407=>295, 408=>746, + 409=>579, 410=>278, 411=>592, 412=>974, 413=>748, 414=>634, 415=>787, 416=>913, 417=>612, 418=>949, 419=>759, 420=>652, 421=>635, 422=>695, 423=>635, 424=>521, + 425=>632, 426=>336, 427=>392, 428=>611, 429=>392, 430=>611, 431=>858, 432=>634, 433=>764, 434=>721, 435=>744, 436=>729, 437=>685, 438=>525, 439=>666, 440=>666, + 441=>578, 442=>525, 443=>636, 444=>666, 445=>578, 446=>510, 447=>635, 448=>295, 449=>492, 450=>459, 451=>295, 452=>1422, 453=>1299, 454=>1154, 455=>835, 456=>787, + 457=>457, 458=>931, 459=>924, 460=>797, 461=>684, 462=>613, 463=>295, 464=>278, 465=>787, 466=>612, 467=>732, 468=>634, 469=>732, 470=>634, 471=>732, 472=>634, + 473=>732, 474=>634, 475=>732, 476=>634, 477=>615, 478=>684, 479=>613, 480=>684, 481=>613, 482=>974, 483=>982, 484=>775, 485=>635, 486=>775, 487=>635, 488=>656, + 489=>579, 490=>787, 491=>612, 492=>787, 493=>612, 494=>666, 495=>578, 496=>278, 497=>1422, 498=>1299, 499=>1154, 500=>775, 501=>635, 502=>1113, 503=>682, 504=>748, + 505=>634, 506=>684, 507=>613, 508=>974, 509=>982, 510=>787, 511=>612, 512=>684, 513=>613, 514=>684, 515=>613, 516=>632, 517=>615, 518=>632, 519=>615, 520=>295, + 521=>278, 522=>295, 523=>278, 524=>787, 525=>612, 526=>787, 527=>612, 528=>695, 529=>411, 530=>695, 531=>411, 532=>732, 533=>634, 534=>732, 535=>634, 536=>635, + 537=>521, 538=>611, 539=>392, 540=>627, 541=>521, 542=>752, 543=>634, 544=>735, 545=>838, 546=>698, 547=>610, 548=>685, 549=>525, 550=>684, 551=>613, 552=>632, + 553=>615, 554=>787, 555=>612, 556=>787, 557=>612, 558=>787, 559=>612, 560=>787, 561=>612, 562=>611, 563=>592, 564=>475, 565=>843, 566=>477, 567=>278, 568=>998, + 569=>998, 570=>684, 571=>698, 572=>550, 573=>557, 574=>611, 575=>521, 576=>525, 577=>603, 578=>479, 579=>686, 580=>732, 581=>684, 582=>632, 583=>615, 584=>295, + 585=>278, 586=>781, 587=>635, 588=>695, 589=>411, 590=>611, 591=>592, 592=>600, 593=>635, 594=>635, 595=>635, 596=>549, 597=>550, 598=>635, 599=>696, 600=>615, + 601=>615, 602=>819, 603=>541, 604=>532, 605=>775, 606=>664, 607=>278, 608=>696, 609=>635, 610=>629, 611=>596, 612=>596, 613=>634, 614=>634, 615=>634, 616=>278, + 617=>338, 618=>372, 619=>396, 620=>487, 621=>278, 622=>706, 623=>974, 624=>974, 625=>974, 626=>646, 627=>642, 628=>634, 629=>612, 630=>858, 631=>728, 632=>660, + 633=>414, 634=>414, 635=>414, 636=>411, 637=>411, 638=>437, 639=>530, 640=>604, 641=>604, 642=>521, 643=>336, 644=>336, 645=>461, 646=>336, 647=>392, 648=>392, + 649=>634, 650=>618, 651=>598, 652=>592, 653=>818, 654=>592, 655=>611, 656=>525, 657=>525, 658=>578, 659=>578, 660=>510, 661=>510, 662=>510, 663=>510, 664=>787, + 665=>580, 666=>664, 667=>708, 668=>654, 669=>292, 670=>667, 671=>507, 672=>727, 673=>510, 674=>510, 675=>1014, 676=>1058, 677=>1013, 678=>824, 679=>610, 680=>778, + 681=>848, 682=>641, 683=>654, 684=>515, 685=>515, 686=>570, 687=>664, 688=>404, 689=>399, 690=>175, 691=>259, 692=>295, 693=>296, 694=>379, 695=>515, 696=>373, + 697=>278, 698=>460, 699=>318, 700=>318, 701=>318, 702=>307, 703=>307, 704=>370, 705=>370, 706=>500, 707=>500, 708=>500, 709=>500, 711=>500, 712=>275, 713=>500, + 714=>500, 715=>500, 716=>275, 717=>500, 718=>500, 719=>500, 720=>337, 721=>337, 722=>307, 723=>307, 724=>500, 725=>500, 726=>413, 727=>500, 728=>500, 729=>500, + 730=>500, 731=>500, 733=>500, 734=>315, 735=>500, 736=>426, 737=>166, 738=>373, 739=>444, 740=>370, 741=>493, 742=>493, 743=>493, 744=>493, 745=>493, 748=>500, + 749=>500, 750=>500, 755=>500, 759=>500, 768=>0, 769=>0, 770=>0, 771=>0, 772=>0, 773=>0, 774=>0, 775=>0, 776=>0, 777=>0, 778=>0, 779=>0, + 780=>0, 781=>0, 782=>0, 783=>0, 784=>0, 785=>0, 786=>0, 787=>0, 788=>0, 789=>0, 790=>0, 791=>0, 792=>0, 793=>0, 794=>0, 795=>0, + 796=>0, 797=>0, 798=>0, 799=>0, 800=>0, 801=>0, 802=>0, 803=>0, 804=>0, 805=>0, 806=>0, 807=>0, 808=>0, 809=>0, 810=>0, 811=>0, + 812=>0, 813=>0, 814=>0, 815=>0, 816=>0, 817=>0, 818=>0, 819=>0, 820=>0, 821=>0, 822=>0, 823=>0, 824=>0, 825=>0, 826=>0, 827=>0, + 828=>0, 829=>0, 830=>0, 831=>0, 832=>0, 833=>0, 834=>0, 835=>0, 836=>0, 837=>0, 838=>0, 839=>0, 840=>0, 841=>0, 842=>0, 843=>0, + 844=>0, 845=>0, 846=>0, 847=>0, 849=>0, 850=>0, 851=>0, 855=>0, 856=>0, 860=>0, 861=>0, 862=>0, 863=>0, 864=>0, 865=>0, 866=>0, + 884=>278, 885=>278, 890=>500, 891=>549, 892=>550, 893=>549, 894=>337, 900=>500, 901=>500, 902=>692, 903=>318, 904=>746, 905=>871, 906=>408, 908=>813, 910=>825, + 911=>826, 912=>338, 913=>684, 914=>686, 915=>557, 916=>684, 917=>632, 918=>685, 919=>752, 920=>787, 921=>295, 922=>656, 923=>684, 924=>863, 925=>748, 926=>632, + 927=>787, 928=>752, 929=>603, 931=>632, 932=>611, 933=>611, 934=>787, 935=>685, 936=>787, 937=>764, 938=>295, 939=>611, 940=>659, 941=>548, 942=>654, 943=>338, + 944=>579, 945=>659, 946=>638, 947=>592, 948=>612, 949=>541, 950=>544, 951=>634, 952=>612, 953=>338, 954=>589, 955=>592, 956=>636, 957=>559, 958=>558, 959=>612, + 960=>602, 961=>635, 962=>587, 963=>634, 964=>602, 965=>579, 966=>660, 967=>578, 968=>660, 969=>837, 970=>338, 971=>579, 972=>612, 973=>579, 974=>837, 976=>614, + 977=>619, 978=>699, 979=>842, 980=>699, 981=>660, 982=>837, 983=>664, 984=>787, 985=>612, 986=>648, 987=>587, 988=>575, 989=>458, 990=>660, 991=>660, 992=>865, + 993=>627, 994=>934, 995=>837, 996=>758, 997=>659, 998=>792, 999=>615, 1000=>687, 1001=>607, 1002=>768, 1003=>625, 1004=>699, 1005=>612, 1006=>611, 1007=>536, 1008=>664, + 1009=>635, 1010=>550, 1011=>278, 1012=>787, 1013=>615, 1014=>615, 1015=>605, 1016=>635, 1017=>698, 1018=>863, 1019=>651, 1020=>635, 1021=>703, 1022=>698, 1023=>703, 1024=>632, + 1025=>632, 1026=>786, 1028=>698, 1029=>635, 1030=>295, 1031=>295, 1032=>295, 1033=>1094, 1034=>1045, 1035=>786, 1037=>748, 1038=>609, 1040=>684, 1041=>686, 1042=>686, 1043=>610, + 1044=>781, 1045=>632, 1046=>1077, 1047=>641, 1048=>748, 1049=>748, 1050=>710, 1051=>752, 1052=>863, 1053=>752, 1054=>787, 1055=>752, 1056=>603, 1057=>698, 1058=>611, 1059=>609, + 1060=>861, 1061=>685, 1062=>776, 1063=>686, 1064=>1069, 1065=>1094, 1066=>833, 1067=>882, 1068=>686, 1069=>698, 1070=>1080, 1071=>695, 1072=>613, 1073=>617, 1074=>589, 1075=>525, + 1076=>691, 1077=>615, 1078=>901, 1079=>532, 1080=>650, 1081=>650, 1082=>604, 1083=>639, 1084=>754, 1085=>654, 1086=>612, 1087=>654, 1088=>635, 1089=>550, 1090=>583, 1091=>592, + 1092=>855, 1093=>592, 1094=>681, 1095=>591, 1096=>915, 1097=>942, 1098=>707, 1099=>790, 1100=>589, 1101=>549, 1102=>842, 1103=>602, 1104=>615, 1105=>615, 1106=>625, 1107=>525, + 1108=>549, 1109=>521, 1110=>278, 1111=>278, 1112=>278, 1113=>902, 1114=>898, 1115=>652, 1117=>650, 1118=>592, 1119=>654, 1120=>934, 1121=>837, 1122=>771, 1123=>672, 1124=>942, + 1125=>749, 1126=>879, 1127=>783, 1128=>1160, 1129=>1001, 1130=>787, 1131=>612, 1132=>1027, 1133=>824, 1134=>636, 1135=>541, 1136=>856, 1137=>876, 1138=>787, 1139=>592, 1140=>781, + 1141=>665, 1142=>781, 1143=>665, 1144=>992, 1145=>904, 1146=>953, 1147=>758, 1148=>1180, 1149=>1028, 1150=>934, 1151=>837, 1152=>698, 1153=>550, 1154=>502, 1155=>0, 1156=>0, + 1157=>0, 1158=>0, 1160=>418, 1161=>418, 1162=>772, 1163=>677, 1164=>686, 1165=>589, 1166=>603, 1167=>635, 1168=>610, 1169=>525, 1170=>675, 1171=>556, 1172=>624, 1173=>530, + 1174=>1077, 1175=>901, 1176=>641, 1177=>532, 1178=>710, 1179=>604, 1180=>710, 1181=>604, 1182=>710, 1183=>604, 1184=>856, 1185=>832, 1186=>752, 1187=>661, 1188=>1014, 1189=>877, + 1190=>1081, 1191=>916, 1192=>796, 1193=>651, 1194=>698, 1195=>550, 1196=>611, 1197=>529, 1198=>611, 1199=>592, 1200=>611, 1201=>592, 1202=>685, 1203=>592, 1204=>934, 1205=>807, + 1206=>686, 1207=>591, 1208=>686, 1209=>591, 1210=>686, 1211=>634, 1212=>941, 1213=>728, 1214=>941, 1215=>728, 1216=>295, 1217=>1077, 1218=>901, 1219=>656, 1220=>604, 1221=>776, + 1222=>670, 1223=>752, 1224=>661, 1225=>776, 1226=>681, 1227=>686, 1228=>591, 1229=>888, 1230=>774, 1231=>278, 1232=>684, 1233=>613, 1234=>684, 1235=>613, 1236=>974, 1237=>982, + 1238=>632, 1239=>615, 1240=>787, 1241=>615, 1242=>787, 1243=>615, 1244=>1077, 1245=>901, 1246=>641, 1247=>532, 1248=>666, 1249=>578, 1250=>748, 1251=>650, 1252=>748, 1253=>650, + 1254=>787, 1255=>612, 1256=>787, 1257=>612, 1258=>787, 1259=>612, 1260=>698, 1261=>549, 1262=>609, 1263=>592, 1264=>609, 1265=>592, 1266=>609, 1267=>592, 1268=>686, 1269=>591, + 1270=>557, 1271=>491, 1272=>882, 1273=>790, 1274=>675, 1275=>556, 1276=>685, 1277=>592, 1278=>685, 1279=>592, 1280=>686, 1281=>589, 1282=>1006, 1283=>897, 1284=>975, 1285=>869, + 1286=>679, 1287=>588, 1288=>1072, 1289=>957, 1290=>1072, 1291=>967, 1292=>775, 1293=>660, 1294=>773, 1295=>711, 1296=>614, 1297=>541, 1298=>752, 1299=>639, 1329=>867, 1330=>732, + 1331=>882, 1332=>882, 1333=>732, 1334=>644, 1335=>682, 1336=>732, 1337=>851, 1338=>882, 1339=>732, 1340=>557, 1341=>824, 1342=>986, 1343=>732, 1344=>707, 1345=>644, 1346=>882, + 1347=>777, 1348=>882, 1349=>732, 1350=>840, 1351=>732, 1352=>732, 1353=>732, 1354=>791, 1355=>644, 1356=>882, 1357=>732, 1358=>882, 1359=>635, 1360=>732, 1361=>732, 1362=>799, + 1363=>861, 1364=>790, 1365=>787, 1366=>635, 1369=>307, 1370=>318, 1371=>500, 1372=>500, 1373=>392, 1374=>526, 1375=>500, 1377=>974, 1378=>634, 1379=>762, 1380=>767, 1381=>634, + 1382=>697, 1383=>533, 1384=>634, 1385=>700, 1386=>697, 1387=>634, 1388=>404, 1389=>894, 1390=>641, 1391=>634, 1392=>634, 1393=>635, 1394=>702, 1395=>634, 1396=>659, 1397=>278, + 1398=>760, 1399=>516, 1400=>634, 1401=>453, 1402=>974, 1403=>516, 1404=>769, 1405=>634, 1406=>696, 1407=>974, 1408=>634, 1409=>635, 1410=>501, 1411=>974, 1412=>648, 1413=>612, + 1414=>629, 1415=>763, 1417=>337, 1418=>433, 1456=>0, 1457=>0, 1458=>0, 1459=>0, 1460=>0, 1461=>0, 1462=>0, 1463=>0, 1464=>0, 1465=>0, 1467=>0, 1468=>0, + 1469=>0, 1471=>0, 1472=>295, 1473=>0, 1474=>0, 1475=>295, 1478=>456, 1479=>0, 1488=>629, 1489=>608, 1490=>448, 1491=>594, 1492=>640, 1493=>272, 1494=>423, 1495=>640, + 1496=>648, 1497=>272, 1498=>592, 1499=>556, 1500=>599, 1501=>640, 1502=>659, 1503=>272, 1504=>441, 1505=>700, 1506=>636, 1507=>640, 1508=>604, 1509=>521, 1510=>581, 1511=>663, + 1512=>592, 1513=>808, 1514=>657, 1520=>471, 1521=>454, 1522=>471, 1548=>323, 1557=>0, 1563=>318, 1567=>531, 1569=>470, 1570=>278, 1571=>278, 1572=>483, 1573=>278, 1574=>783, + 1575=>278, 1576=>941, 1577=>524, 1578=>941, 1579=>941, 1580=>646, 1581=>646, 1582=>646, 1583=>445, 1584=>445, 1585=>483, 1586=>483, 1587=>1221, 1588=>1221, 1589=>1209, 1590=>1209, + 1591=>925, 1592=>925, 1593=>597, 1594=>597, 1600=>293, 1601=>1037, 1602=>776, 1603=>824, 1604=>727, 1605=>619, 1606=>734, 1607=>524, 1608=>483, 1609=>783, 1610=>783, 1611=>0, + 1612=>0, 1613=>0, 1614=>0, 1615=>0, 1616=>0, 1617=>0, 1618=>0, 1619=>0, 1620=>0, 1621=>0, 1626=>500, 1632=>537, 1633=>537, 1634=>537, 1635=>537, 1636=>537, + 1637=>537, 1638=>537, 1639=>537, 1640=>537, 1641=>537, 1642=>537, 1643=>325, 1644=>318, 1645=>545, 1646=>941, 1647=>776, 1652=>292, 1657=>941, 1658=>941, 1659=>941, 1660=>941, + 1661=>941, 1662=>941, 1663=>941, 1664=>941, 1665=>646, 1666=>646, 1667=>646, 1668=>646, 1669=>646, 1670=>646, 1671=>646, 1681=>483, 1682=>483, 1685=>610, 1688=>483, 1697=>1037, + 1700=>1037, 1702=>1037, 1705=>895, 1711=>895, 1717=>727, 1722=>734, 1727=>646, 1734=>483, 1740=>783, 1742=>783, 1749=>524, 1776=>537, 1777=>537, 1778=>537, 1779=>537, 1780=>537, + 1781=>537, 1782=>537, 1783=>537, 1784=>537, 1785=>537, 3647=>652, 3713=>670, 3714=>684, 3716=>688, 3719=>482, 3720=>628, 3722=>684, 3725=>688, 3732=>669, 3733=>642, 3734=>645, + 3735=>655, 3737=>659, 3738=>625, 3739=>625, 3740=>745, 3741=>767, 3742=>687, 3743=>687, 3745=>702, 3746=>688, 3747=>684, 3749=>649, 3751=>632, 3754=>703, 3755=>819, 3757=>633, + 3758=>684, 3759=>788, 3760=>632, 3761=>0, 3762=>539, 3763=>539, 3764=>0, 3765=>0, 3766=>0, 3767=>0, 3768=>0, 3769=>0, 3771=>0, 3772=>0, 3773=>663, 3776=>375, + 3777=>657, 3778=>460, 3779=>547, 3780=>491, 3782=>674, 3784=>0, 3785=>0, 3786=>0, 3787=>0, 3788=>0, 3789=>0, 3804=>1028, 3805=>1028, 5121=>684, 5122=>684, 5123=>684, + 5124=>684, 5125=>769, 5126=>769, 5127=>769, 5129=>769, 5130=>769, 5131=>769, 5132=>835, 5133=>834, 5134=>835, 5135=>834, 5136=>835, 5137=>834, 5138=>967, 5139=>1007, 5140=>967, + 5141=>1007, 5142=>769, 5143=>967, 5144=>1007, 5145=>967, 5146=>1007, 5147=>769, 5149=>256, 5150=>543, 5151=>423, 5152=>423, 5153=>389, 5154=>389, 5155=>393, 5156=>389, 5157=>466, + 5158=>385, 5159=>256, 5160=>389, 5161=>389, 5162=>389, 5163=>1090, 5164=>909, 5165=>953, 5166=>1117, 5167=>684, 5168=>684, 5169=>684, 5170=>684, 5171=>729, 5172=>729, 5173=>729, + 5175=>729, 5176=>729, 5177=>729, 5178=>835, 5179=>834, 5180=>835, 5181=>834, 5182=>835, 5183=>834, 5184=>967, 5185=>1007, 5186=>967, 5187=>1007, 5188=>967, 5189=>1007, 5190=>967, + 5191=>1007, 5192=>729, 5193=>508, 5194=>192, 5196=>732, 5197=>732, 5198=>732, 5199=>732, 5200=>730, 5201=>730, 5202=>730, 5204=>730, 5205=>730, 5206=>730, 5207=>921, 5208=>889, + 5209=>921, 5210=>889, 5211=>921, 5212=>889, 5213=>928, 5214=>900, 5215=>928, 5216=>900, 5217=>947, 5218=>900, 5219=>947, 5220=>900, 5221=>947, 5222=>434, 5223=>877, 5224=>877, + 5225=>866, 5226=>890, 5227=>628, 5228=>628, 5229=>628, 5230=>628, 5231=>628, 5232=>694, 5233=>628, 5234=>628, 5235=>628, 5236=>860, 5237=>771, 5238=>815, 5239=>816, 5240=>815, + 5241=>816, 5242=>860, 5243=>771, 5244=>860, 5245=>771, 5246=>815, 5247=>816, 5248=>815, 5249=>816, 5250=>815, 5251=>407, 5252=>407, 5253=>750, 5254=>775, 5255=>750, 5256=>775, + 5257=>628, 5258=>628, 5259=>628, 5260=>628, 5261=>628, 5262=>628, 5263=>628, 5264=>628, 5265=>628, 5266=>860, 5267=>771, 5268=>815, 5269=>816, 5270=>815, 5271=>816, 5272=>860, + 5273=>771, 5274=>860, 5275=>771, 5276=>815, 5277=>816, 5278=>815, 5279=>816, 5280=>815, 5281=>435, 5282=>435, 5283=>610, 5284=>557, 5285=>557, 5286=>557, 5287=>610, 5288=>522, + 5289=>610, 5290=>557, 5291=>557, 5292=>749, 5293=>769, 5294=>746, 5295=>764, 5296=>746, 5297=>764, 5298=>749, 5299=>769, 5300=>749, 5301=>769, 5302=>746, 5303=>764, 5304=>746, + 5305=>764, 5306=>746, 5307=>386, 5308=>508, 5309=>386, 5312=>852, 5313=>852, 5314=>852, 5315=>823, 5316=>852, 5317=>852, 5318=>852, 5319=>852, 5320=>852, 5321=>1069, 5322=>1035, + 5323=>1059, 5324=>852, 5325=>1059, 5326=>852, 5327=>852, 5328=>600, 5329=>453, 5330=>600, 5331=>852, 5332=>852, 5333=>852, 5334=>852, 5335=>852, 5336=>852, 5337=>852, 5338=>852, + 5339=>852, 5340=>1069, 5341=>1035, 5342=>1059, 5343=>1030, 5344=>1059, 5345=>1030, 5346=>1069, 5347=>1035, 5348=>1069, 5349=>1035, 5350=>1083, 5351=>1030, 5352=>1083, 5353=>1030, 5354=>600, + 5356=>729, 5357=>603, 5358=>603, 5359=>603, 5360=>603, 5361=>603, 5362=>661, 5363=>603, 5364=>603, 5365=>603, 5366=>834, 5367=>754, 5368=>792, 5369=>771, 5370=>792, 5371=>771, + 5372=>834, 5373=>754, 5374=>834, 5375=>754, 5376=>792, 5377=>771, 5378=>792, 5379=>771, 5380=>792, 5381=>418, 5382=>420, 5383=>418, 5392=>712, 5393=>712, 5394=>712, 5395=>892, + 5396=>892, 5397=>892, 5398=>892, 5399=>910, 5400=>872, 5401=>910, 5402=>872, 5403=>910, 5404=>872, 5405=>1140, 5406=>1100, 5407=>1140, 5408=>1100, 5409=>1140, 5410=>1100, 5411=>1140, + 5412=>1100, 5413=>641, 5414=>627, 5415=>627, 5416=>627, 5417=>627, 5418=>627, 5419=>667, 5420=>627, 5421=>627, 5422=>627, 5423=>844, 5424=>781, 5425=>816, 5426=>818, 5427=>816, + 5428=>818, 5429=>844, 5430=>781, 5431=>844, 5432=>781, 5433=>816, 5434=>818, 5435=>816, 5436=>818, 5437=>816, 5438=>418, 5440=>389, 5441=>484, 5442=>916, 5443=>916, 5444=>916, + 5445=>916, 5446=>916, 5447=>916, 5448=>603, 5449=>603, 5450=>603, 5451=>603, 5452=>603, 5453=>603, 5454=>834, 5455=>754, 5456=>418, 5458=>729, 5459=>684, 5460=>684, 5461=>684, + 5462=>684, 5463=>726, 5464=>726, 5465=>726, 5466=>726, 5467=>924, 5468=>1007, 5469=>508, 5470=>732, 5471=>732, 5472=>732, 5473=>732, 5474=>732, 5475=>732, 5476=>730, 5477=>730, + 5478=>730, 5479=>730, 5480=>947, 5481=>900, 5482=>508, 5492=>831, 5493=>831, 5494=>831, 5495=>831, 5496=>831, 5497=>831, 5498=>831, 5499=>563, 5500=>752, 5501=>484, 5502=>1047, + 5503=>1047, 5504=>1047, 5505=>1047, 5506=>1047, 5507=>1047, 5508=>1047, 5509=>825, 5514=>831, 5515=>831, 5516=>831, 5517=>831, 5518=>1259, 5519=>1259, 5520=>1259, 5521=>1002, 5522=>1002, + 5523=>1259, 5524=>1259, 5525=>700, 5526=>1073, 5536=>852, 5537=>852, 5538=>852, 5539=>852, 5540=>852, 5541=>852, 5542=>600, 5543=>643, 5544=>643, 5545=>643, 5546=>643, 5547=>643, + 5548=>643, 5549=>643, 5550=>418, 5551=>628, 5598=>770, 5601=>767, 5702=>468, 5703=>468, 5742=>444, 5743=>1047, 5744=>1310, 5745=>1632, 5746=>1632, 5747=>1375, 5748=>1375, 5749=>1632, + 5750=>1632, 7424=>592, 7425=>717, 7426=>982, 7427=>586, 7428=>550, 7429=>605, 7430=>605, 7431=>491, 7432=>541, 7433=>278, 7434=>395, 7435=>579, 7436=>583, 7437=>754, 7438=>650, + 7439=>612, 7440=>550, 7441=>684, 7442=>684, 7443=>684, 7444=>1023, 7446=>612, 7447=>612, 7448=>524, 7449=>602, 7450=>602, 7451=>583, 7452=>574, 7453=>737, 7454=>948, 7455=>638, + 7456=>592, 7457=>818, 7458=>525, 7459=>526, 7462=>583, 7463=>592, 7464=>564, 7465=>524, 7466=>590, 7467=>639, 7468=>431, 7469=>613, 7470=>432, 7472=>485, 7473=>398, 7474=>398, + 7475=>488, 7476=>474, 7477=>186, 7478=>186, 7479=>413, 7480=>351, 7481=>543, 7482=>471, 7483=>471, 7484=>496, 7485=>439, 7486=>380, 7487=>438, 7488=>385, 7489=>461, 7490=>623, + 7491=>392, 7492=>392, 7493=>405, 7494=>648, 7495=>428, 7496=>405, 7497=>417, 7498=>417, 7499=>360, 7500=>359, 7501=>405, 7502=>179, 7503=>426, 7504=>623, 7505=>409, 7506=>414, + 7507=>370, 7508=>414, 7509=>414, 7510=>428, 7511=>295, 7512=>405, 7513=>470, 7514=>623, 7515=>417, 7517=>402, 7518=>373, 7519=>385, 7520=>416, 7521=>364, 7522=>179, 7523=>259, + 7524=>405, 7525=>417, 7526=>402, 7527=>373, 7528=>385, 7529=>416, 7530=>364, 7543=>635, 7544=>474, 7547=>372, 7557=>278, 7579=>405, 7580=>370, 7581=>370, 7582=>414, 7583=>360, + 7584=>296, 7585=>233, 7586=>405, 7587=>405, 7588=>261, 7589=>250, 7590=>261, 7591=>261, 7592=>234, 7593=>250, 7594=>235, 7595=>376, 7596=>623, 7597=>623, 7598=>411, 7599=>479, + 7600=>409, 7601=>414, 7602=>414, 7603=>360, 7604=>287, 7605=>295, 7606=>508, 7607=>418, 7608=>361, 7609=>406, 7610=>417, 7611=>366, 7612=>437, 7613=>366, 7614=>392, 7615=>414, + 7620=>0, 7621=>0, 7622=>0, 7623=>0, 7624=>0, 7625=>0, 7680=>684, 7681=>613, 7682=>686, 7683=>635, 7684=>686, 7685=>635, 7686=>686, 7687=>635, 7688=>698, 7689=>550, + 7690=>770, 7691=>635, 7692=>770, 7693=>635, 7694=>770, 7695=>635, 7696=>770, 7697=>635, 7698=>770, 7699=>635, 7700=>632, 7701=>615, 7702=>632, 7703=>615, 7704=>632, 7705=>615, + 7706=>632, 7707=>615, 7708=>632, 7709=>615, 7710=>575, 7711=>352, 7712=>775, 7713=>635, 7714=>752, 7715=>634, 7716=>752, 7717=>634, 7718=>752, 7719=>634, 7720=>752, 7721=>634, + 7722=>752, 7723=>634, 7724=>295, 7725=>278, 7726=>295, 7727=>278, 7728=>656, 7729=>579, 7730=>656, 7731=>579, 7732=>656, 7733=>579, 7734=>557, 7735=>288, 7736=>557, 7737=>288, + 7738=>557, 7739=>278, 7740=>557, 7741=>278, 7742=>863, 7743=>974, 7744=>863, 7745=>974, 7746=>863, 7747=>974, 7748=>748, 7749=>634, 7750=>748, 7751=>634, 7752=>748, 7753=>634, + 7754=>748, 7755=>634, 7756=>787, 7757=>612, 7758=>787, 7759=>612, 7760=>787, 7761=>612, 7762=>787, 7763=>612, 7764=>603, 7765=>635, 7766=>603, 7767=>635, 7768=>695, 7769=>411, + 7770=>695, 7771=>411, 7772=>695, 7773=>411, 7774=>695, 7775=>411, 7776=>635, 7777=>521, 7778=>635, 7779=>521, 7780=>635, 7781=>521, 7782=>635, 7783=>521, 7784=>635, 7785=>521, + 7786=>611, 7787=>392, 7788=>611, 7789=>392, 7790=>611, 7791=>392, 7792=>611, 7793=>392, 7794=>732, 7795=>634, 7796=>732, 7797=>634, 7798=>732, 7799=>634, 7800=>732, 7801=>634, + 7802=>732, 7803=>634, 7804=>684, 7805=>592, 7806=>684, 7807=>592, 7808=>989, 7809=>818, 7810=>989, 7811=>818, 7812=>989, 7813=>818, 7814=>989, 7815=>818, 7816=>989, 7817=>818, + 7818=>685, 7819=>592, 7820=>685, 7821=>592, 7822=>611, 7823=>592, 7824=>685, 7825=>525, 7826=>685, 7827=>525, 7828=>685, 7829=>525, 7830=>634, 7831=>392, 7832=>818, 7833=>592, + 7834=>613, 7835=>352, 7840=>684, 7841=>613, 7842=>684, 7843=>613, 7844=>684, 7845=>613, 7846=>684, 7847=>613, 7848=>684, 7849=>613, 7850=>684, 7851=>613, 7852=>684, 7853=>613, + 7854=>684, 7855=>613, 7856=>684, 7857=>613, 7858=>684, 7859=>613, 7860=>684, 7861=>613, 7862=>684, 7863=>613, 7864=>632, 7865=>615, 7866=>632, 7867=>615, 7868=>632, 7869=>615, + 7870=>632, 7871=>615, 7872=>632, 7873=>615, 7874=>632, 7875=>615, 7876=>632, 7877=>615, 7878=>632, 7879=>615, 7880=>295, 7881=>278, 7882=>295, 7883=>278, 7884=>787, 7885=>612, + 7886=>787, 7887=>612, 7888=>787, 7889=>612, 7890=>787, 7891=>612, 7892=>787, 7893=>612, 7894=>787, 7895=>612, 7896=>787, 7897=>612, 7898=>913, 7899=>612, 7900=>913, 7901=>612, + 7902=>913, 7903=>612, 7904=>913, 7905=>612, 7906=>913, 7907=>612, 7908=>732, 7909=>634, 7910=>732, 7911=>634, 7912=>858, 7913=>634, 7914=>858, 7915=>634, 7916=>858, 7917=>634, + 7918=>858, 7919=>634, 7920=>858, 7921=>634, 7922=>611, 7923=>592, 7924=>611, 7925=>592, 7926=>611, 7927=>592, 7928=>611, 7929=>592, 7936=>659, 7937=>659, 7938=>659, 7939=>659, + 7940=>659, 7941=>659, 7942=>659, 7943=>659, 7944=>684, 7945=>684, 7946=>877, 7947=>877, 7948=>769, 7949=>801, 7950=>708, 7951=>743, 7952=>541, 7953=>541, 7954=>541, 7955=>541, + 7956=>541, 7957=>541, 7960=>711, 7961=>711, 7962=>966, 7963=>975, 7964=>898, 7965=>928, 7968=>634, 7969=>634, 7970=>634, 7971=>634, 7972=>634, 7973=>634, 7974=>634, 7975=>634, + 7976=>837, 7977=>835, 7978=>1086, 7979=>1089, 7980=>1027, 7981=>1051, 7982=>934, 7983=>947, 7984=>338, 7985=>338, 7986=>338, 7987=>338, 7988=>338, 7989=>338, 7990=>338, 7991=>338, + 7992=>380, 7993=>374, 7994=>635, 7995=>635, 7996=>570, 7997=>600, 7998=>489, 7999=>493, 8000=>612, 8001=>612, 8002=>612, 8003=>612, 8004=>612, 8005=>612, 8008=>804, 8009=>848, + 8010=>1095, 8011=>1100, 8012=>938, 8013=>970, 8016=>579, 8017=>579, 8018=>579, 8019=>579, 8020=>579, 8021=>579, 8022=>579, 8023=>579, 8025=>784, 8027=>998, 8029=>1012, 8031=>897, + 8032=>837, 8033=>837, 8034=>837, 8035=>837, 8036=>837, 8037=>837, 8038=>837, 8039=>837, 8040=>802, 8041=>843, 8042=>1089, 8043=>1095, 8044=>946, 8045=>972, 8046=>921, 8047=>952, + 8048=>659, 8049=>659, 8050=>541, 8051=>548, 8052=>634, 8053=>654, 8054=>338, 8055=>338, 8056=>612, 8057=>612, 8058=>579, 8059=>579, 8060=>837, 8061=>837, 8064=>659, 8065=>659, + 8066=>659, 8067=>659, 8068=>659, 8069=>659, 8070=>659, 8071=>659, 8072=>684, 8073=>684, 8074=>877, 8075=>877, 8076=>769, 8077=>801, 8078=>708, 8079=>743, 8080=>634, 8081=>634, + 8082=>634, 8083=>634, 8084=>634, 8085=>634, 8086=>634, 8087=>634, 8088=>837, 8089=>835, 8090=>1086, 8091=>1089, 8092=>1027, 8093=>1051, 8094=>934, 8095=>947, 8096=>837, 8097=>837, + 8098=>837, 8099=>837, 8100=>837, 8101=>837, 8102=>837, 8103=>837, 8104=>802, 8105=>843, 8106=>1089, 8107=>1095, 8108=>946, 8109=>972, 8110=>921, 8111=>952, 8112=>659, 8113=>659, + 8114=>659, 8115=>659, 8116=>659, 8118=>659, 8119=>659, 8120=>684, 8121=>684, 8122=>716, 8123=>692, 8124=>684, 8125=>500, 8126=>500, 8127=>500, 8128=>500, 8129=>500, 8130=>634, + 8131=>634, 8132=>654, 8134=>634, 8135=>634, 8136=>805, 8137=>746, 8138=>931, 8139=>871, 8140=>752, 8141=>500, 8142=>500, 8143=>500, 8144=>338, 8145=>338, 8146=>338, 8147=>338, + 8150=>338, 8151=>338, 8152=>295, 8153=>295, 8154=>475, 8155=>408, 8157=>500, 8158=>500, 8159=>500, 8160=>579, 8161=>579, 8162=>579, 8163=>579, 8164=>635, 8165=>635, 8166=>579, + 8167=>579, 8168=>611, 8169=>611, 8170=>845, 8171=>825, 8172=>685, 8173=>500, 8174=>500, 8175=>500, 8178=>837, 8179=>837, 8180=>837, 8182=>837, 8183=>837, 8184=>941, 8185=>813, + 8186=>922, 8187=>826, 8188=>764, 8189=>500, 8190=>500, 8192=>500, 8193=>1000, 8194=>500, 8195=>1000, 8196=>330, 8197=>250, 8198=>167, 8199=>636, 8200=>318, 8201=>200, 8202=>100, + 8203=>0, 8204=>0, 8205=>0, 8206=>0, 8207=>0, 8208=>361, 8209=>361, 8210=>636, 8213=>1000, 8214=>500, 8215=>500, 8219=>318, 8223=>518, 8227=>590, 8228=>334, 8229=>667, + 8231=>318, 8234=>0, 8235=>0, 8236=>0, 8237=>0, 8238=>0, 8239=>200, 8241=>1735, 8242=>227, 8243=>374, 8244=>520, 8245=>227, 8246=>374, 8247=>520, 8248=>339, 8251=>838, + 8252=>485, 8253=>531, 8254=>500, 8255=>804, 8256=>804, 8257=>250, 8258=>1000, 8259=>500, 8260=>167, 8261=>390, 8262=>390, 8263=>922, 8264=>733, 8265=>733, 8266=>497, 8267=>636, + 8268=>500, 8269=>500, 8270=>500, 8271=>337, 8272=>804, 8273=>500, 8274=>450, 8275=>838, 8276=>804, 8277=>838, 8278=>586, 8279=>663, 8280=>838, 8281=>838, 8282=>318, 8283=>797, + 8284=>838, 8285=>318, 8286=>318, 8287=>222, 8288=>0, 8289=>0, 8290=>0, 8291=>0, 8298=>0, 8299=>0, 8300=>0, 8301=>0, 8302=>0, 8303=>0, 8304=>401, 8305=>179, + 8308=>401, 8309=>401, 8310=>401, 8311=>401, 8312=>401, 8313=>401, 8314=>528, 8315=>528, 8316=>528, 8317=>246, 8318=>246, 8319=>398, 8320=>401, 8321=>401, 8322=>401, 8323=>401, + 8324=>401, 8325=>401, 8326=>401, 8327=>401, 8328=>401, 8329=>401, 8330=>528, 8331=>528, 8332=>528, 8333=>246, 8334=>246, 8336=>392, 8337=>417, 8338=>414, 8339=>444, 8340=>417, + 8352=>877, 8353=>636, 8354=>636, 8355=>636, 8356=>636, 8357=>974, 8358=>748, 8359=>1272, 8360=>1074, 8361=>989, 8362=>784, 8363=>636, 8365=>636, 8366=>636, 8367=>1272, 8368=>636, + 8369=>636, 8370=>636, 8371=>636, 8372=>774, 8373=>641, 8400=>0, 8401=>0, 8406=>0, 8407=>0, 8448=>1019, 8449=>1019, 8450=>698, 8451=>1123, 8452=>642, 8453=>1019, 8454=>1067, + 8455=>614, 8456=>698, 8457=>952, 8459=>988, 8460=>754, 8461=>850, 8462=>634, 8463=>634, 8464=>470, 8465=>697, 8466=>720, 8467=>413, 8468=>818, 8469=>801, 8470=>1040, 8471=>1000, + 8472=>697, 8473=>702, 8474=>787, 8475=>798, 8476=>814, 8477=>792, 8478=>896, 8479=>684, 8480=>1020, 8481=>1074, 8483=>684, 8484=>745, 8485=>578, 8486=>764, 8487=>764, 8488=>616, + 8489=>338, 8490=>656, 8491=>684, 8492=>786, 8493=>703, 8494=>854, 8495=>592, 8496=>605, 8497=>786, 8498=>575, 8499=>1069, 8500=>462, 8501=>745, 8502=>674, 8503=>469, 8504=>648, + 8505=>380, 8506=>926, 8507=>1194, 8508=>702, 8509=>728, 8510=>655, 8511=>849, 8512=>811, 8513=>775, 8514=>557, 8515=>557, 8516=>611, 8517=>819, 8518=>708, 8519=>615, 8520=>351, + 8521=>351, 8523=>780, 8526=>526, 8531=>969, 8532=>969, 8533=>969, 8534=>969, 8535=>969, 8536=>969, 8537=>969, 8538=>969, 8539=>969, 8540=>969, 8541=>969, 8542=>969, 8543=>568, + 8544=>295, 8545=>492, 8546=>689, 8547=>923, 8548=>684, 8549=>922, 8550=>1120, 8551=>1317, 8552=>917, 8553=>685, 8554=>933, 8555=>1131, 8556=>557, 8557=>698, 8558=>770, 8559=>863, + 8560=>278, 8561=>458, 8562=>637, 8563=>812, 8564=>592, 8565=>811, 8566=>991, 8567=>1170, 8568=>819, 8569=>592, 8570=>822, 8571=>1002, 8572=>278, 8573=>550, 8574=>635, 8575=>974, + 8576=>1245, 8577=>770, 8578=>1245, 8579=>703, 8580=>549, 8592=>838, 8593=>838, 8594=>838, 8595=>838, 8596=>838, 8597=>838, 8598=>838, 8599=>838, 8600=>838, 8601=>838, 8602=>838, + 8603=>838, 8604=>838, 8605=>838, 8606=>838, 8607=>838, 8608=>838, 8609=>838, 8610=>838, 8611=>838, 8612=>838, 8613=>838, 8614=>838, 8615=>838, 8616=>838, 8617=>838, 8618=>838, + 8619=>838, 8620=>838, 8621=>838, 8622=>838, 8623=>838, 8624=>838, 8625=>838, 8626=>838, 8627=>838, 8628=>838, 8629=>838, 8630=>838, 8631=>838, 8632=>838, 8633=>838, 8634=>838, + 8635=>838, 8636=>838, 8637=>838, 8638=>838, 8639=>838, 8640=>838, 8641=>838, 8642=>838, 8643=>838, 8644=>838, 8645=>838, 8646=>838, 8647=>838, 8648=>838, 8649=>838, 8650=>838, + 8651=>838, 8652=>838, 8653=>838, 8654=>838, 8655=>838, 8656=>838, 8657=>838, 8658=>838, 8659=>838, 8660=>838, 8661=>838, 8662=>838, 8663=>838, 8664=>838, 8665=>838, 8666=>838, + 8667=>838, 8668=>838, 8669=>838, 8670=>838, 8671=>838, 8672=>838, 8673=>838, 8674=>838, 8675=>838, 8676=>838, 8677=>838, 8678=>838, 8679=>838, 8680=>838, 8681=>838, 8682=>838, + 8683=>838, 8684=>838, 8685=>838, 8686=>838, 8687=>838, 8688=>838, 8689=>838, 8690=>838, 8691=>838, 8692=>838, 8693=>838, 8694=>838, 8695=>838, 8696=>838, 8697=>838, 8698=>838, + 8699=>838, 8700=>838, 8701=>838, 8702=>838, 8703=>838, 8704=>684, 8705=>636, 8706=>517, 8707=>632, 8708=>632, 8709=>871, 8710=>669, 8711=>669, 8712=>871, 8713=>871, 8714=>718, + 8715=>871, 8716=>871, 8717=>718, 8718=>636, 8719=>757, 8720=>757, 8721=>674, 8722=>838, 8723=>838, 8724=>838, 8725=>167, 8726=>637, 8727=>838, 8728=>626, 8729=>318, 8730=>637, + 8731=>637, 8732=>637, 8733=>677, 8734=>833, 8735=>838, 8736=>896, 8737=>896, 8738=>838, 8739=>500, 8740=>500, 8741=>500, 8742=>500, 8743=>732, 8744=>732, 8745=>732, 8746=>732, + 8747=>521, 8748=>789, 8749=>1057, 8750=>521, 8751=>789, 8752=>1057, 8753=>521, 8754=>521, 8755=>521, 8756=>636, 8757=>636, 8758=>260, 8759=>636, 8760=>838, 8761=>838, 8762=>838, + 8763=>838, 8764=>838, 8765=>838, 8766=>838, 8767=>838, 8768=>375, 8769=>838, 8770=>838, 8771=>838, 8772=>838, 8773=>838, 8774=>838, 8775=>838, 8776=>838, 8777=>838, 8778=>838, + 8779=>838, 8780=>838, 8781=>838, 8782=>838, 8783=>838, 8784=>838, 8785=>838, 8786=>839, 8787=>839, 8788=>1000, 8789=>1000, 8790=>838, 8791=>838, 8792=>838, 8793=>838, 8794=>838, + 8795=>838, 8796=>838, 8797=>838, 8798=>838, 8799=>838, 8800=>838, 8801=>838, 8802=>838, 8803=>838, 8804=>838, 8805=>838, 8806=>838, 8807=>838, 8808=>838, 8809=>838, 8810=>1047, + 8811=>1047, 8812=>464, 8813=>838, 8814=>838, 8815=>838, 8816=>838, 8817=>838, 8818=>838, 8819=>838, 8820=>838, 8821=>838, 8822=>838, 8823=>838, 8824=>838, 8825=>838, 8826=>838, + 8827=>838, 8828=>838, 8829=>838, 8830=>838, 8831=>838, 8832=>838, 8833=>838, 8834=>838, 8835=>838, 8836=>838, 8837=>838, 8838=>838, 8839=>838, 8840=>838, 8841=>838, 8842=>838, + 8843=>838, 8844=>732, 8845=>732, 8846=>732, 8847=>838, 8848=>838, 8849=>838, 8850=>838, 8851=>722, 8852=>722, 8853=>838, 8854=>838, 8855=>838, 8856=>838, 8857=>838, 8858=>838, + 8859=>838, 8860=>838, 8861=>838, 8862=>838, 8863=>838, 8864=>838, 8865=>838, 8866=>871, 8867=>871, 8868=>871, 8869=>871, 8870=>521, 8871=>521, 8872=>871, 8873=>871, 8874=>871, + 8875=>871, 8876=>871, 8877=>871, 8878=>871, 8879=>871, 8882=>838, 8883=>838, 8884=>838, 8885=>838, 8886=>1000, 8887=>1000, 8888=>838, 8889=>838, 8890=>521, 8891=>732, 8892=>732, + 8893=>732, 8896=>820, 8897=>820, 8898=>820, 8899=>820, 8900=>494, 8901=>318, 8902=>626, 8904=>1000, 8905=>1000, 8906=>1000, 8907=>1000, 8908=>1000, 8909=>838, 8918=>838, 8919=>838, + 8920=>1422, 8921=>1422, 8922=>838, 8923=>838, 8924=>838, 8925=>838, 8926=>838, 8927=>838, 8928=>838, 8929=>838, 8930=>838, 8931=>838, 8932=>838, 8933=>838, 8934=>838, 8935=>838, + 8936=>838, 8937=>838, 8938=>838, 8939=>838, 8940=>838, 8941=>838, 8946=>1000, 8947=>871, 8948=>718, 8949=>871, 8950=>871, 8951=>718, 8952=>871, 8953=>871, 8954=>1000, 8955=>871, + 8956=>718, 8957=>871, 8958=>718, 8959=>871, 8962=>635, 8966=>871, 8968=>390, 8969=>390, 8970=>390, 8971=>390, 8976=>838, 8977=>513, 8984=>1000, 8985=>838, 8992=>521, 8993=>521, + 8997=>1000, 9000=>1443, 9085=>757, 9115=>500, 9116=>500, 9117=>500, 9118=>500, 9119=>500, 9120=>500, 9121=>500, 9122=>500, 9123=>500, 9124=>500, 9125=>500, 9126=>500, 9127=>750, + 9128=>750, 9129=>750, 9130=>750, 9131=>750, 9132=>750, 9133=>750, 9134=>521, 9166=>838, 9167=>945, 9250=>635, 9251=>635, 9312=>896, 9313=>896, 9314=>896, 9315=>896, 9316=>896, + 9317=>896, 9318=>896, 9319=>896, 9320=>896, 9321=>896, 9600=>769, 9601=>769, 9602=>769, 9603=>769, 9604=>769, 9605=>769, 9606=>769, 9607=>769, 9608=>769, 9609=>769, 9610=>769, + 9611=>769, 9612=>769, 9613=>769, 9614=>769, 9615=>769, 9616=>769, 9617=>769, 9618=>769, 9619=>769, 9620=>769, 9621=>769, 9622=>769, 9623=>769, 9624=>769, 9625=>769, 9626=>769, + 9627=>769, 9628=>769, 9629=>769, 9630=>769, 9631=>769, 9632=>945, 9633=>945, 9634=>945, 9635=>945, 9636=>945, 9637=>945, 9638=>945, 9639=>945, 9640=>945, 9641=>945, 9642=>678, + 9643=>678, 9644=>945, 9645=>945, 9646=>550, 9647=>550, 9648=>769, 9649=>769, 9650=>769, 9651=>769, 9652=>502, 9653=>502, 9654=>769, 9655=>769, 9656=>502, 9657=>502, 9658=>769, + 9659=>769, 9660=>769, 9661=>769, 9662=>502, 9663=>502, 9664=>769, 9665=>769, 9666=>502, 9667=>502, 9668=>769, 9669=>769, 9670=>769, 9671=>769, 9672=>769, 9673=>873, 9674=>494, + 9675=>873, 9676=>873, 9677=>873, 9678=>873, 9679=>873, 9680=>873, 9681=>873, 9682=>873, 9683=>873, 9684=>873, 9685=>873, 9686=>527, 9687=>527, 9688=>791, 9689=>970, 9690=>970, + 9691=>970, 9692=>387, 9693=>387, 9694=>387, 9695=>387, 9696=>873, 9697=>873, 9698=>769, 9699=>769, 9700=>769, 9701=>769, 9702=>590, 9703=>945, 9704=>945, 9705=>945, 9706=>945, + 9707=>945, 9708=>769, 9709=>769, 9710=>769, 9711=>1119, 9712=>945, 9713=>945, 9714=>945, 9715=>945, 9716=>873, 9717=>873, 9718=>873, 9719=>873, 9720=>769, 9721=>769, 9722=>769, + 9723=>830, 9724=>830, 9725=>732, 9726=>732, 9727=>769, 9728=>896, 9729=>1000, 9730=>896, 9731=>896, 9732=>896, 9733=>896, 9734=>896, 9735=>573, 9736=>896, 9737=>896, 9738=>888, + 9739=>888, 9740=>671, 9741=>1013, 9742=>1246, 9743=>1250, 9744=>896, 9745=>896, 9746=>896, 9747=>532, 9748=>896, 9749=>896, 9750=>896, 9751=>896, 9752=>896, 9753=>896, 9754=>896, + 9755=>896, 9756=>896, 9757=>609, 9758=>896, 9759=>609, 9760=>896, 9761=>896, 9762=>896, 9763=>896, 9764=>669, 9765=>746, 9766=>649, 9767=>784, 9768=>545, 9769=>896, 9770=>896, + 9771=>896, 9772=>710, 9773=>896, 9774=>896, 9775=>896, 9776=>896, 9777=>896, 9778=>896, 9779=>896, 9780=>896, 9781=>896, 9782=>896, 9783=>896, 9784=>896, 9785=>896, 9786=>896, + 9787=>896, 9788=>896, 9789=>896, 9790=>896, 9791=>614, 9792=>731, 9793=>731, 9794=>896, 9795=>896, 9796=>896, 9797=>896, 9798=>896, 9799=>896, 9800=>896, 9801=>896, 9802=>896, + 9803=>896, 9804=>896, 9805=>896, 9806=>896, 9807=>896, 9808=>896, 9809=>896, 9810=>896, 9811=>896, 9812=>896, 9813=>896, 9814=>896, 9815=>896, 9816=>896, 9817=>896, 9818=>896, + 9819=>896, 9820=>896, 9821=>896, 9822=>896, 9823=>896, 9824=>896, 9825=>896, 9826=>896, 9827=>896, 9828=>896, 9829=>896, 9830=>896, 9831=>896, 9832=>896, 9833=>472, 9834=>638, + 9835=>896, 9836=>896, 9837=>472, 9838=>357, 9839=>484, 9840=>748, 9841=>766, 9842=>896, 9843=>896, 9844=>896, 9845=>896, 9846=>896, 9847=>896, 9848=>896, 9849=>896, 9850=>896, + 9851=>896, 9852=>896, 9853=>896, 9854=>896, 9855=>896, 9856=>869, 9857=>869, 9858=>869, 9859=>869, 9860=>869, 9861=>869, 9862=>896, 9863=>896, 9864=>896, 9865=>896, 9866=>896, + 9867=>896, 9868=>896, 9869=>896, 9870=>896, 9871=>896, 9872=>896, 9873=>896, 9874=>896, 9875=>896, 9876=>896, 9877=>541, 9878=>896, 9879=>896, 9880=>896, 9881=>896, 9882=>896, + 9883=>896, 9884=>896, 9888=>896, 9889=>702, 9890=>838, 9891=>838, 9892=>838, 9893=>838, 9894=>838, 9895=>838, 9896=>838, 9897=>838, 9898=>838, 9899=>838, 9900=>838, 9901=>838, + 9902=>838, 9903=>838, 9904=>844, 9905=>838, 9906=>731, 9985=>838, 9986=>838, 9987=>838, 9988=>838, 9990=>838, 9991=>838, 9992=>838, 9993=>838, 9996=>838, 9997=>838, 9998=>838, + 9999=>838, 10000=>838, 10001=>838, 10002=>838, 10003=>838, 10004=>838, 10005=>838, 10006=>838, 10007=>838, 10008=>838, 10009=>838, 10010=>838, 10011=>838, 10012=>838, 10013=>838, 10014=>838, + 10015=>838, 10016=>838, 10017=>838, 10018=>838, 10019=>838, 10020=>838, 10021=>838, 10022=>838, 10023=>838, 10025=>838, 10026=>838, 10027=>838, 10028=>838, 10029=>838, 10030=>838, 10031=>838, + 10032=>838, 10033=>838, 10034=>838, 10035=>838, 10036=>838, 10037=>838, 10038=>838, 10039=>838, 10040=>838, 10041=>838, 10042=>838, 10043=>838, 10044=>838, 10045=>838, 10046=>838, 10047=>838, + 10048=>838, 10049=>838, 10050=>838, 10051=>838, 10052=>838, 10053=>838, 10054=>838, 10055=>838, 10056=>838, 10057=>838, 10058=>838, 10059=>838, 10061=>896, 10063=>896, 10064=>896, 10065=>896, + 10066=>896, 10070=>896, 10072=>838, 10073=>838, 10074=>838, 10075=>322, 10076=>322, 10077=>538, 10078=>538, 10081=>838, 10082=>838, 10083=>838, 10084=>838, 10085=>838, 10086=>838, 10087=>838, + 10088=>838, 10089=>838, 10090=>838, 10091=>838, 10092=>838, 10093=>838, 10094=>838, 10095=>838, 10096=>838, 10097=>838, 10098=>838, 10099=>838, 10100=>838, 10101=>838, 10102=>896, 10103=>896, + 10104=>896, 10105=>896, 10106=>896, 10107=>896, 10108=>896, 10109=>896, 10110=>896, 10111=>896, 10112=>838, 10113=>838, 10114=>838, 10115=>838, 10116=>838, 10117=>838, 10118=>838, 10119=>838, + 10120=>838, 10121=>838, 10122=>838, 10123=>838, 10124=>838, 10125=>838, 10126=>838, 10127=>838, 10128=>838, 10129=>838, 10130=>838, 10131=>838, 10132=>838, 10136=>838, 10137=>838, 10138=>838, + 10139=>838, 10140=>838, 10141=>838, 10142=>838, 10143=>838, 10144=>838, 10145=>838, 10146=>838, 10147=>838, 10148=>838, 10149=>838, 10150=>838, 10151=>838, 10152=>838, 10153=>838, 10154=>838, + 10155=>838, 10156=>838, 10157=>838, 10158=>838, 10159=>838, 10161=>838, 10162=>838, 10163=>838, 10164=>838, 10165=>838, 10166=>838, 10167=>838, 10168=>838, 10169=>838, 10170=>838, 10171=>838, + 10172=>838, 10173=>838, 10174=>838, 10208=>494, 10214=>495, 10215=>495, 10216=>390, 10217=>390, 10218=>556, 10219=>556, 10224=>838, 10225=>838, 10226=>838, 10227=>838, 10228=>1157, 10229=>1434, + 10230=>1434, 10231=>1434, 10232=>1434, 10233=>1434, 10234=>1434, 10235=>1434, 10236=>1434, 10237=>1434, 10238=>1434, 10239=>1434, 10240=>732, 10241=>732, 10242=>732, 10243=>732, 10244=>732, 10245=>732, + 10246=>732, 10247=>732, 10248=>732, 10249=>732, 10250=>732, 10251=>732, 10252=>732, 10253=>732, 10254=>732, 10255=>732, 10256=>732, 10257=>732, 10258=>732, 10259=>732, 10260=>732, 10261=>732, + 10262=>732, 10263=>732, 10264=>732, 10265=>732, 10266=>732, 10267=>732, 10268=>732, 10269=>732, 10270=>732, 10271=>732, 10272=>732, 10273=>732, 10274=>732, 10275=>732, 10276=>732, 10277=>732, + 10278=>732, 10279=>732, 10280=>732, 10281=>732, 10282=>732, 10283=>732, 10284=>732, 10285=>732, 10286=>732, 10287=>732, 10288=>732, 10289=>732, 10290=>732, 10291=>732, 10292=>732, 10293=>732, + 10294=>732, 10295=>732, 10296=>732, 10297=>732, 10298=>732, 10299=>732, 10300=>732, 10301=>732, 10302=>732, 10303=>732, 10304=>732, 10305=>732, 10306=>732, 10307=>732, 10308=>732, 10309=>732, + 10310=>732, 10311=>732, 10312=>732, 10313=>732, 10314=>732, 10315=>732, 10316=>732, 10317=>732, 10318=>732, 10319=>732, 10320=>732, 10321=>732, 10322=>732, 10323=>732, 10324=>732, 10325=>732, + 10326=>732, 10327=>732, 10328=>732, 10329=>732, 10330=>732, 10331=>732, 10332=>732, 10333=>732, 10334=>732, 10335=>732, 10336=>732, 10337=>732, 10338=>732, 10339=>732, 10340=>732, 10341=>732, + 10342=>732, 10343=>732, 10344=>732, 10345=>732, 10346=>732, 10347=>732, 10348=>732, 10349=>732, 10350=>732, 10351=>732, 10352=>732, 10353=>732, 10354=>732, 10355=>732, 10356=>732, 10357=>732, + 10358=>732, 10359=>732, 10360=>732, 10361=>732, 10362=>732, 10363=>732, 10364=>732, 10365=>732, 10366=>732, 10367=>732, 10368=>732, 10369=>732, 10370=>732, 10371=>732, 10372=>732, 10373=>732, + 10374=>732, 10375=>732, 10376=>732, 10377=>732, 10378=>732, 10379=>732, 10380=>732, 10381=>732, 10382=>732, 10383=>732, 10384=>732, 10385=>732, 10386=>732, 10387=>732, 10388=>732, 10389=>732, + 10390=>732, 10391=>732, 10392=>732, 10393=>732, 10394=>732, 10395=>732, 10396=>732, 10397=>732, 10398=>732, 10399=>732, 10400=>732, 10401=>732, 10402=>732, 10403=>732, 10404=>732, 10405=>732, + 10406=>732, 10407=>732, 10408=>732, 10409=>732, 10410=>732, 10411=>732, 10412=>732, 10413=>732, 10414=>732, 10415=>732, 10416=>732, 10417=>732, 10418=>732, 10419=>732, 10420=>732, 10421=>732, + 10422=>732, 10423=>732, 10424=>732, 10425=>732, 10426=>732, 10427=>732, 10428=>732, 10429=>732, 10430=>732, 10431=>732, 10432=>732, 10433=>732, 10434=>732, 10435=>732, 10436=>732, 10437=>732, + 10438=>732, 10439=>732, 10440=>732, 10441=>732, 10442=>732, 10443=>732, 10444=>732, 10445=>732, 10446=>732, 10447=>732, 10448=>732, 10449=>732, 10450=>732, 10451=>732, 10452=>732, 10453=>732, + 10454=>732, 10455=>732, 10456=>732, 10457=>732, 10458=>732, 10459=>732, 10460=>732, 10461=>732, 10462=>732, 10463=>732, 10464=>732, 10465=>732, 10466=>732, 10467=>732, 10468=>732, 10469=>732, + 10470=>732, 10471=>732, 10472=>732, 10473=>732, 10474=>732, 10475=>732, 10476=>732, 10477=>732, 10478=>732, 10479=>732, 10480=>732, 10481=>732, 10482=>732, 10483=>732, 10484=>732, 10485=>732, + 10486=>732, 10487=>732, 10488=>732, 10489=>732, 10490=>732, 10491=>732, 10492=>732, 10493=>732, 10494=>732, 10495=>732, 10502=>838, 10503=>838, 10506=>838, 10507=>838, 10560=>683, 10561=>683, + 10702=>838, 10703=>1000, 10704=>1000, 10705=>1000, 10706=>1000, 10707=>1000, 10708=>1000, 10709=>1000, 10731=>494, 10752=>1000, 10753=>1000, 10754=>1000, 10764=>1325, 10765=>521, 10766=>521, 10767=>521, + 10768=>521, 10769=>521, 10770=>521, 10771=>521, 10772=>521, 10773=>521, 10774=>521, 10775=>521, 10776=>521, 10777=>521, 10778=>521, 10779=>521, 10780=>521, 10877=>838, 10878=>838, 10879=>838, + 10880=>838, 10881=>838, 10882=>838, 10883=>838, 10884=>838, 10885=>838, 10886=>838, 10887=>838, 10888=>838, 10889=>838, 10890=>838, 10891=>838, 10892=>838, 10893=>838, 10894=>838, 10895=>838, + 10896=>838, 10897=>838, 10898=>838, 10899=>838, 10900=>838, 10901=>838, 10902=>838, 10903=>838, 10904=>838, 10905=>838, 10906=>838, 10907=>838, 10908=>838, 10909=>838, 10910=>838, 10911=>838, + 10912=>838, 10926=>838, 10927=>838, 10928=>838, 10929=>838, 10930=>838, 10931=>838, 10932=>838, 10933=>838, 10934=>838, 10935=>838, 10936=>838, 10937=>838, 10938=>838, 11001=>838, 11002=>838, + 11008=>838, 11009=>838, 11010=>838, 11011=>838, 11012=>838, 11013=>838, 11014=>838, 11015=>838, 11016=>838, 11017=>838, 11018=>838, 11019=>838, 11020=>838, 11021=>838, 11022=>836, 11023=>836, + 11024=>836, 11025=>836, 11026=>945, 11027=>945, 11028=>945, 11029=>945, 11030=>769, 11031=>769, 11032=>769, 11033=>769, 11034=>945, 11040=>869, 11041=>873, 11042=>873, 11043=>873, 11360=>557, + 11361=>278, 11362=>557, 11363=>603, 11364=>695, 11365=>613, 11366=>392, 11367=>752, 11368=>634, 11369=>656, 11370=>579, 11371=>685, 11372=>525, 11380=>592, 11381=>654, 11382=>568, 11383=>660, + 61440=>977, 61441=>977, 61960=>781, 62047=>592, 63173=>612, 64256=>689, 64257=>630, 64258=>630, 64259=>967, 64260=>967, 64261=>686, 64262=>861, 64275=>1202, 64276=>1202, 64277=>1196, 64278=>1186, + 64279=>1529, 64285=>296, 64287=>494, 64288=>636, 64297=>838, 64298=>799, 64299=>799, 64300=>799, 64301=>799, 64302=>663, 64303=>663, 64304=>663, 64305=>655, 64306=>454, 64307=>607, 64308=>690, + 64309=>336, 64310=>437, 64312=>683, 64313=>336, 64314=>642, 64315=>666, 64316=>635, 64318=>736, 64320=>456, 64321=>771, 64323=>651, 64324=>666, 64326=>639, 64327=>688, 64328=>642, 64329=>799, + 64330=>726, 64331=>272, 64332=>655, 64333=>666, 64334=>666, 64338=>941, 64339=>982, 64340=>278, 64341=>302, 64342=>941, 64343=>982, 64344=>278, 64345=>302, 64346=>941, 64347=>982, 64348=>278, + 64349=>302, 64350=>941, 64351=>982, 64352=>278, 64353=>302, 64354=>941, 64355=>982, 64356=>278, 64357=>302, 64358=>941, 64359=>982, 64360=>278, 64361=>302, 64362=>1037, 64363=>1035, 64364=>478, + 64365=>506, 64366=>1037, 64367=>1035, 64368=>478, 64369=>506, 64370=>646, 64371=>646, 64372=>618, 64373=>646, 64374=>646, 64375=>646, 64376=>618, 64377=>646, 64378=>646, 64379=>646, 64380=>618, + 64381=>646, 64382=>646, 64383=>646, 64384=>618, 64385=>646, 64394=>483, 64395=>552, 64396=>483, 64397=>552, 64398=>895, 64399=>895, 64400=>476, 64401=>552, 64402=>895, 64403=>895, 64404=>476, + 64405=>552, 64414=>734, 64415=>761, 64473=>483, 64474=>517, 64488=>278, 64489=>302, 64508=>783, 64509=>833, 64510=>278, 64511=>302, 65024=>0, 65025=>0, 65026=>0, 65027=>0, 65028=>0, + 65029=>0, 65030=>0, 65031=>0, 65032=>0, 65033=>0, 65034=>0, 65035=>0, 65036=>0, 65037=>0, 65038=>0, 65039=>0, 65136=>293, 65137=>293, 65138=>293, 65139=>262, 65140=>293, + 65142=>293, 65143=>293, 65144=>293, 65145=>293, 65146=>293, 65147=>293, 65148=>293, 65149=>293, 65150=>293, 65151=>293, 65152=>470, 65153=>278, 65154=>305, 65155=>278, 65156=>305, 65157=>483, + 65158=>517, 65159=>278, 65160=>305, 65161=>783, 65162=>833, 65163=>278, 65164=>302, 65165=>278, 65166=>305, 65167=>941, 65168=>982, 65169=>278, 65170=>302, 65171=>524, 65172=>536, 65173=>941, + 65174=>982, 65175=>278, 65176=>302, 65177=>941, 65178=>982, 65179=>278, 65180=>302, 65181=>646, 65182=>646, 65183=>618, 65184=>646, 65185=>646, 65186=>646, 65187=>618, 65188=>646, 65189=>646, + 65190=>646, 65191=>618, 65192=>646, 65193=>445, 65194=>525, 65195=>445, 65196=>525, 65197=>483, 65198=>552, 65199=>483, 65200=>552, 65201=>1221, 65202=>1275, 65203=>838, 65204=>892, 65205=>1221, + 65206=>1275, 65207=>838, 65208=>892, 65209=>1209, 65210=>1225, 65211=>849, 65212=>867, 65213=>1209, 65214=>1225, 65215=>849, 65216=>867, 65217=>925, 65218=>949, 65219=>796, 65220=>820, 65221=>925, + 65222=>949, 65223=>796, 65224=>820, 65225=>597, 65226=>532, 65227=>597, 65228=>482, 65229=>597, 65230=>532, 65231=>523, 65232=>482, 65233=>1037, 65234=>1035, 65235=>478, 65236=>506, 65237=>776, + 65238=>834, 65239=>478, 65240=>506, 65241=>824, 65242=>843, 65243=>476, 65244=>552, 65245=>727, 65246=>757, 65247=>305, 65248=>331, 65249=>619, 65250=>666, 65251=>536, 65252=>578, 65253=>734, + 65254=>761, 65255=>278, 65256=>302, 65257=>524, 65258=>536, 65259=>527, 65260=>461, 65261=>483, 65262=>517, 65263=>783, 65264=>833, 65265=>783, 65266=>833, 65267=>278, 65268=>302, 65269=>570, + 65270=>597, 65271=>570, 65272=>597, 65273=>570, 65274=>597, 65275=>570, 65276=>597, 65279=>0, 65533=>1025}; + font[:enc]=''; + font[:diff]=''; + font[:file]='DejaVuSans.z'; + font[:ctg]='DejaVuSans.ctg.z'; + font[:originalsize]=520788; +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/dejavusansb.rb b/lib/plugins/rfpdf/lib/fonts/dejavusansb.rb new file mode 100644 index 000000000..e7629f695 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/dejavusansb.rb @@ -0,0 +1,287 @@ +TCPDFFontDescriptor.define('dejavusansb') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='DejaVuSans-Bold'; + font[:desc]={'Ascent'=>928,'Descent'=>-236,'CapHeight'=>928,'Flags'=>32,'FontBBox'=>'[-1069 -388 1975 1123]','ItalicAngle'=>0,'StemV'=>120,'MissingWidth'=>600}; + font[:up]=-42; + font[:ut]=44; + font[:cw]={ + 0=>600, 32=>348, 33=>456, 34=>521, 35=>838, 36=>696, 37=>1002, 38=>872, 39=>306, 40=>457, 41=>457, 42=>523, 43=>838, 44=>380, 45=>415, 46=>380, + 47=>365, 48=>696, 49=>696, 50=>696, 51=>696, 52=>696, 53=>696, 54=>696, 55=>696, 56=>696, 57=>696, 58=>400, 59=>400, 60=>838, 61=>838, 62=>838, + 63=>580, 64=>1000, 65=>774, 66=>762, 67=>734, 68=>830, 69=>683, 70=>683, 71=>821, 72=>837, 73=>372, 74=>372, 75=>775, 76=>637, 77=>995, 78=>837, + 79=>850, 80=>733, 81=>850, 82=>770, 83=>720, 84=>682, 85=>812, 86=>774, 87=>1103, 88=>771, 89=>724, 90=>725, 91=>457, 92=>365, 93=>457, 94=>838, + 95=>500, 96=>500, 97=>675, 98=>716, 99=>593, 100=>716, 101=>678, 102=>435, 103=>716, 104=>712, 105=>343, 106=>343, 107=>665, 108=>343, 109=>1042, 110=>712, + 111=>687, 112=>716, 113=>716, 114=>493, 115=>595, 116=>478, 117=>712, 118=>652, 119=>924, 120=>645, 121=>652, 122=>582, 123=>712, 124=>365, 125=>712, 126=>838, + 8364=>696, 1027=>637, 8218=>380, 402=>435, 8222=>657, 8230=>1000, 8224=>500, 8225=>500, 710=>500, 8240=>1440, 352=>720, 8249=>412, 338=>1167, 1036=>817, 381=>725, 1039=>837, + 8216=>380, 8217=>380, 8220=>657, 8221=>657, 8226=>639, 8211=>500, 8212=>1000, 732=>500, 8482=>1000, 353=>595, 8250=>412, 339=>1094, 1116=>679, 382=>582, 376=>724, 160=>348, + 161=>456, 162=>696, 163=>696, 164=>636, 165=>696, 166=>365, 167=>500, 168=>500, 169=>1000, 170=>564, 171=>646, 172=>838, 173=>415, 174=>1000, 175=>500, 176=>500, + 177=>838, 178=>438, 179=>438, 180=>500, 181=>736, 182=>636, 183=>380, 184=>500, 185=>438, 186=>564, 187=>646, 188=>1035, 189=>1035, 190=>1035, 191=>580, 192=>774, + 193=>774, 194=>774, 195=>774, 196=>774, 197=>774, 198=>1085, 199=>734, 200=>683, 201=>683, 202=>683, 203=>683, 204=>372, 205=>372, 206=>372, 207=>372, 208=>838, + 209=>837, 210=>850, 211=>850, 212=>850, 213=>850, 214=>850, 215=>838, 216=>850, 217=>812, 218=>812, 219=>812, 220=>812, 221=>724, 222=>738, 223=>719, 224=>675, + 225=>675, 226=>675, 227=>675, 228=>675, 229=>675, 230=>1048, 231=>593, 232=>678, 233=>678, 234=>678, 235=>678, 236=>343, 237=>343, 238=>343, 239=>343, 240=>687, + 241=>712, 242=>687, 243=>687, 244=>687, 245=>687, 246=>687, 247=>838, 248=>687, 249=>712, 250=>712, 251=>712, 252=>712, 253=>652, 254=>716, 255=>652, 256=>774, + 257=>675, 258=>774, 259=>675, 260=>774, 261=>675, 262=>734, 263=>593, 264=>734, 265=>593, 266=>734, 267=>593, 268=>734, 269=>593, 270=>830, 271=>716, 272=>838, + 273=>716, 274=>683, 275=>678, 276=>683, 277=>678, 278=>683, 279=>678, 280=>683, 281=>678, 282=>683, 283=>678, 284=>821, 285=>716, 286=>821, 287=>716, 288=>821, + 289=>716, 290=>821, 291=>716, 292=>837, 293=>712, 294=>974, 295=>790, 296=>372, 297=>343, 298=>372, 299=>343, 300=>372, 301=>343, 302=>372, 303=>343, 304=>372, + 305=>343, 306=>744, 307=>686, 308=>372, 309=>343, 310=>775, 311=>665, 312=>665, 313=>637, 314=>343, 315=>637, 316=>343, 317=>637, 318=>479, 319=>637, 320=>557, + 321=>642, 322=>371, 323=>837, 324=>712, 325=>837, 326=>712, 327=>837, 328=>712, 329=>983, 330=>837, 331=>712, 332=>850, 333=>687, 334=>850, 335=>687, 336=>850, + 337=>687, 340=>770, 341=>493, 342=>770, 343=>493, 344=>770, 345=>493, 346=>720, 347=>595, 348=>720, 349=>595, 350=>720, 351=>595, 354=>682, 355=>478, 356=>682, + 357=>478, 358=>682, 359=>478, 360=>812, 361=>712, 362=>812, 363=>712, 364=>812, 365=>712, 366=>812, 367=>712, 368=>812, 369=>712, 370=>812, 371=>712, 372=>1103, + 373=>924, 374=>724, 375=>652, 377=>725, 378=>582, 379=>725, 380=>582, 383=>435, 384=>716, 385=>811, 386=>762, 387=>716, 388=>762, 389=>716, 390=>734, 391=>734, + 392=>593, 393=>838, 394=>879, 395=>757, 396=>716, 397=>688, 398=>683, 399=>849, 400=>696, 401=>683, 403=>821, 404=>793, 405=>1045, 406=>436, 407=>389, 408=>775, + 409=>665, 410=>360, 411=>592, 412=>1042, 413=>837, 414=>712, 415=>850, 416=>874, 417=>687, 418=>1114, 419=>962, 420=>782, 421=>716, 422=>770, 423=>720, 424=>595, + 425=>683, 426=>552, 427=>478, 428=>707, 429=>478, 430=>682, 431=>835, 432=>712, 433=>769, 434=>813, 435=>797, 436=>778, 437=>725, 438=>582, 439=>772, 440=>772, + 441=>641, 442=>582, 443=>696, 444=>772, 445=>641, 446=>573, 447=>716, 448=>372, 449=>659, 450=>544, 451=>372, 452=>1555, 453=>1412, 454=>1298, 455=>1009, 456=>980, + 457=>686, 458=>1209, 459=>1180, 460=>1055, 461=>774, 462=>675, 463=>372, 464=>343, 465=>850, 466=>687, 467=>812, 468=>712, 469=>812, 470=>712, 471=>812, 472=>712, + 473=>812, 474=>712, 475=>812, 476=>712, 477=>678, 478=>774, 479=>675, 480=>774, 481=>675, 482=>1085, 483=>1048, 484=>821, 485=>716, 486=>821, 487=>716, 488=>775, + 489=>665, 490=>850, 491=>687, 492=>850, 493=>687, 494=>772, 495=>582, 496=>343, 497=>1555, 498=>1412, 499=>1298, 500=>821, 501=>716, 502=>1289, 503=>787, 504=>837, + 505=>712, 506=>774, 507=>675, 508=>1085, 509=>1048, 510=>850, 511=>687, 512=>774, 513=>675, 514=>774, 515=>675, 516=>683, 517=>678, 518=>683, 519=>678, 520=>372, + 521=>343, 522=>372, 523=>343, 524=>850, 525=>687, 526=>850, 527=>687, 528=>770, 529=>493, 530=>770, 531=>493, 532=>812, 533=>712, 534=>812, 535=>712, 536=>720, + 537=>595, 538=>682, 539=>478, 540=>690, 541=>607, 542=>837, 543=>712, 544=>837, 545=>865, 546=>809, 547=>659, 548=>725, 549=>582, 550=>774, 551=>675, 552=>683, + 553=>678, 554=>850, 555=>687, 556=>850, 557=>687, 558=>850, 559=>687, 560=>850, 561=>687, 562=>724, 563=>652, 564=>492, 565=>867, 566=>512, 567=>343, 568=>1088, + 569=>1088, 570=>774, 571=>734, 572=>593, 573=>637, 574=>682, 575=>595, 576=>582, 577=>782, 578=>614, 579=>762, 580=>812, 581=>774, 582=>683, 583=>678, 584=>372, + 585=>343, 586=>860, 587=>791, 588=>770, 589=>493, 590=>724, 591=>652, 592=>675, 593=>716, 594=>716, 595=>716, 596=>593, 597=>593, 598=>717, 599=>792, 600=>678, + 601=>678, 602=>876, 603=>557, 604=>545, 605=>815, 606=>731, 607=>343, 608=>792, 609=>716, 610=>627, 611=>735, 612=>635, 613=>712, 614=>712, 615=>712, 616=>545, + 617=>440, 618=>545, 619=>559, 620=>693, 621=>343, 622=>841, 623=>1042, 624=>1042, 625=>1042, 626=>712, 627=>793, 628=>642, 629=>687, 630=>909, 631=>681, 632=>796, + 633=>538, 634=>538, 635=>650, 636=>493, 637=>493, 638=>596, 639=>596, 640=>642, 641=>642, 642=>595, 643=>415, 644=>435, 645=>605, 646=>552, 647=>478, 648=>478, + 649=>920, 650=>769, 651=>670, 652=>652, 653=>924, 654=>652, 655=>724, 656=>694, 657=>684, 658=>641, 659=>641, 660=>573, 661=>573, 662=>573, 663=>573, 664=>850, + 665=>633, 666=>731, 667=>685, 668=>691, 669=>343, 670=>732, 671=>539, 672=>792, 673=>573, 674=>573, 675=>1156, 676=>1214, 677=>1155, 678=>974, 679=>769, 680=>929, + 681=>1026, 682=>792, 683=>780, 684=>591, 685=>415, 686=>677, 687=>789, 688=>456, 689=>456, 690=>219, 691=>315, 692=>315, 693=>315, 694=>411, 695=>591, 696=>417, + 697=>302, 698=>521, 699=>380, 700=>380, 701=>380, 702=>366, 703=>366, 704=>326, 705=>326, 706=>500, 707=>500, 708=>500, 709=>500, 711=>500, 712=>306, 713=>500, + 714=>500, 715=>500, 716=>306, 717=>500, 718=>500, 719=>500, 720=>337, 721=>337, 722=>366, 723=>366, 724=>500, 725=>500, 726=>500, 727=>500, 728=>500, 729=>500, + 730=>500, 731=>500, 733=>500, 734=>351, 735=>500, 736=>412, 737=>219, 738=>381, 739=>413, 740=>326, 741=>500, 742=>500, 743=>500, 744=>500, 745=>500, 748=>500, + 749=>500, 750=>500, 755=>500, 759=>500, 768=>0, 769=>0, 770=>0, 771=>0, 772=>0, 773=>0, 774=>0, 775=>0, 776=>0, 777=>0, 778=>0, 779=>0, + 780=>0, 781=>0, 782=>0, 783=>0, 784=>0, 785=>0, 786=>0, 787=>0, 788=>0, 789=>0, 790=>0, 791=>0, 792=>0, 793=>0, 794=>0, 795=>0, + 796=>0, 797=>0, 798=>0, 799=>0, 800=>0, 801=>0, 802=>0, 803=>0, 804=>0, 805=>0, 806=>0, 807=>0, 808=>0, 809=>0, 810=>0, 811=>0, + 812=>0, 813=>0, 814=>0, 815=>0, 816=>0, 817=>0, 818=>0, 819=>0, 820=>0, 821=>0, 822=>0, 823=>0, 824=>0, 825=>0, 826=>0, 827=>0, + 828=>0, 829=>0, 830=>0, 831=>0, 832=>0, 833=>0, 834=>0, 835=>0, 836=>0, 837=>0, 838=>0, 839=>0, 840=>0, 841=>0, 842=>0, 843=>0, + 844=>0, 845=>0, 846=>0, 847=>0, 849=>0, 850=>0, 851=>0, 855=>0, 856=>0, 860=>0, 861=>0, 862=>0, 863=>0, 864=>0, 865=>0, 866=>0, + 884=>302, 885=>302, 890=>500, 891=>593, 892=>550, 893=>549, 894=>337, 900=>441, 901=>500, 902=>797, 903=>380, 904=>846, 905=>1009, 906=>563, 908=>891, 910=>980, + 911=>894, 912=>390, 913=>774, 914=>762, 915=>637, 916=>774, 917=>683, 918=>725, 919=>837, 920=>850, 921=>372, 922=>775, 923=>774, 924=>995, 925=>837, 926=>632, + 927=>850, 928=>837, 929=>733, 931=>683, 932=>682, 933=>724, 934=>850, 935=>771, 936=>850, 937=>850, 938=>372, 939=>724, 940=>687, 941=>557, 942=>712, 943=>390, + 944=>675, 945=>687, 946=>716, 947=>681, 948=>687, 949=>557, 950=>591, 951=>712, 952=>687, 953=>390, 954=>710, 955=>633, 956=>736, 957=>681, 958=>591, 959=>687, + 960=>791, 961=>716, 962=>593, 963=>779, 964=>638, 965=>675, 966=>782, 967=>645, 968=>794, 969=>869, 970=>390, 971=>675, 972=>687, 973=>675, 974=>869, 976=>651, + 977=>661, 978=>746, 979=>981, 980=>746, 981=>796, 982=>869, 983=>744, 984=>850, 985=>687, 986=>734, 987=>593, 988=>683, 989=>494, 990=>702, 991=>660, 992=>919, + 993=>627, 994=>1093, 995=>837, 996=>832, 997=>716, 998=>928, 999=>744, 1000=>733, 1001=>650, 1002=>789, 1003=>671, 1004=>752, 1005=>716, 1006=>682, 1007=>590, 1008=>744, + 1009=>716, 1010=>593, 1011=>343, 1012=>850, 1013=>645, 1014=>644, 1015=>738, 1016=>716, 1017=>734, 1018=>995, 1019=>732, 1020=>716, 1021=>698, 1022=>734, 1023=>698, 1024=>683, + 1025=>683, 1026=>878, 1028=>734, 1029=>720, 1030=>372, 1031=>372, 1032=>372, 1033=>1154, 1034=>1130, 1035=>878, 1037=>837, 1038=>771, 1040=>774, 1041=>762, 1042=>762, 1043=>637, + 1044=>891, 1045=>683, 1046=>1224, 1047=>710, 1048=>837, 1049=>837, 1050=>817, 1051=>831, 1052=>995, 1053=>837, 1054=>850, 1055=>837, 1056=>733, 1057=>734, 1058=>682, 1059=>771, + 1060=>992, 1061=>771, 1062=>928, 1063=>808, 1064=>1235, 1065=>1326, 1066=>939, 1067=>1036, 1068=>762, 1069=>734, 1070=>1174, 1071=>770, 1072=>675, 1073=>698, 1074=>633, 1075=>522, + 1076=>808, 1077=>678, 1078=>995, 1079=>581, 1080=>701, 1081=>701, 1082=>679, 1083=>732, 1084=>817, 1085=>691, 1086=>687, 1087=>691, 1088=>716, 1089=>593, 1090=>580, 1091=>652, + 1092=>992, 1093=>645, 1094=>741, 1095=>687, 1096=>1062, 1097=>1105, 1098=>751, 1099=>904, 1100=>632, 1101=>593, 1102=>972, 1103=>642, 1104=>678, 1105=>678, 1106=>714, 1107=>522, + 1108=>593, 1109=>595, 1110=>343, 1111=>343, 1112=>343, 1113=>991, 1114=>956, 1115=>734, 1117=>701, 1118=>652, 1119=>691, 1120=>1093, 1121=>869, 1122=>840, 1123=>736, 1124=>1012, + 1125=>839, 1126=>992, 1127=>832, 1128=>1358, 1129=>1121, 1130=>850, 1131=>687, 1132=>1236, 1133=>1007, 1134=>696, 1135=>557, 1136=>1075, 1137=>1061, 1138=>850, 1139=>667, 1140=>850, + 1141=>695, 1142=>850, 1143=>695, 1144=>1148, 1145=>1043, 1146=>1074, 1147=>863, 1148=>1405, 1149=>1173, 1150=>1093, 1151=>869, 1152=>734, 1153=>593, 1154=>652, 1155=>0, 1156=>0, + 1157=>0, 1158=>0, 1160=>418, 1161=>418, 1162=>957, 1163=>807, 1164=>762, 1165=>611, 1166=>733, 1167=>716, 1168=>637, 1169=>522, 1170=>666, 1171=>543, 1172=>808, 1173=>669, + 1174=>1224, 1175=>995, 1176=>710, 1177=>581, 1178=>775, 1179=>679, 1180=>817, 1181=>679, 1182=>817, 1183=>679, 1184=>1015, 1185=>826, 1186=>956, 1187=>808, 1188=>1103, 1189=>874, + 1190=>1273, 1191=>1017, 1192=>875, 1193=>710, 1194=>734, 1195=>593, 1196=>682, 1197=>580, 1198=>724, 1199=>652, 1200=>724, 1201=>652, 1202=>771, 1203=>645, 1204=>1112, 1205=>1000, + 1206=>808, 1207=>687, 1208=>808, 1209=>687, 1210=>808, 1211=>712, 1212=>1026, 1213=>810, 1214=>1026, 1215=>810, 1216=>372, 1217=>1224, 1218=>995, 1219=>775, 1220=>630, 1221=>951, + 1222=>805, 1223=>837, 1224=>691, 1225=>957, 1226=>807, 1227=>808, 1228=>687, 1229=>1115, 1230=>933, 1231=>343, 1232=>774, 1233=>675, 1234=>774, 1235=>675, 1236=>1085, 1237=>1048, + 1238=>683, 1239=>678, 1240=>849, 1241=>678, 1242=>849, 1243=>678, 1244=>1224, 1245=>995, 1246=>710, 1247=>581, 1248=>772, 1249=>641, 1250=>837, 1251=>701, 1252=>837, 1253=>701, + 1254=>850, 1255=>687, 1256=>850, 1257=>687, 1258=>850, 1259=>687, 1260=>734, 1261=>593, 1262=>771, 1263=>652, 1264=>771, 1265=>652, 1266=>771, 1267=>652, 1268=>808, 1269=>687, + 1270=>637, 1271=>522, 1272=>1036, 1273=>904, 1274=>666, 1275=>543, 1276=>771, 1277=>645, 1278=>771, 1279=>645, 1280=>762, 1281=>608, 1282=>1159, 1283=>893, 1284=>1119, 1285=>920, + 1286=>828, 1287=>693, 1288=>1242, 1289=>1017, 1290=>1248, 1291=>1013, 1292=>839, 1293=>638, 1294=>938, 1295=>803, 1296=>696, 1297=>557, 1298=>831, 1299=>732, 1329=>984, 1330=>812, + 1331=>984, 1332=>984, 1333=>812, 1334=>777, 1335=>812, 1336=>812, 1337=>975, 1338=>984, 1339=>812, 1340=>710, 1341=>1078, 1342=>1136, 1343=>812, 1344=>710, 1345=>757, 1346=>984, + 1347=>876, 1348=>984, 1349=>793, 1350=>984, 1351=>812, 1352=>812, 1353=>812, 1354=>958, 1355=>777, 1356=>984, 1357=>812, 1358=>984, 1359=>720, 1360=>812, 1361=>793, 1362=>895, + 1363=>850, 1364=>936, 1365=>850, 1366=>720, 1369=>366, 1370=>380, 1371=>550, 1372=>550, 1373=>380, 1374=>546, 1375=>521, 1377=>1042, 1378=>712, 1379=>866, 1380=>868, 1381=>712, + 1382=>817, 1383=>653, 1384=>712, 1385=>811, 1386=>817, 1387=>712, 1388=>498, 1389=>1018, 1390=>716, 1391=>712, 1392=>712, 1393=>716, 1394=>819, 1395=>712, 1396=>751, 1397=>343, + 1398=>882, 1399=>559, 1400=>712, 1401=>559, 1402=>1042, 1403=>559, 1404=>863, 1405=>712, 1406=>813, 1407=>1042, 1408=>712, 1409=>716, 1410=>571, 1411=>1042, 1412=>778, 1413=>687, + 1414=>720, 1415=>862, 1417=>400, 1418=>487, 1456=>0, 1457=>0, 1458=>0, 1459=>0, 1460=>0, 1461=>0, 1462=>0, 1463=>0, 1464=>0, 1465=>0, 1467=>0, 1468=>0, + 1469=>0, 1471=>0, 1472=>372, 1473=>0, 1474=>0, 1475=>372, 1478=>532, 1479=>0, 1488=>751, 1489=>731, 1490=>537, 1491=>684, 1492=>778, 1493=>372, 1494=>521, 1495=>778, + 1496=>770, 1497=>372, 1498=>778, 1499=>750, 1500=>718, 1501=>778, 1502=>856, 1503=>372, 1504=>532, 1505=>855, 1506=>720, 1507=>802, 1508=>777, 1509=>628, 1510=>751, 1511=>803, + 1512=>778, 1513=>963, 1514=>822, 1520=>692, 1521=>692, 1522=>692, 1548=>380, 1557=>0, 1563=>400, 1567=>580, 1569=>511, 1570=>343, 1571=>343, 1572=>622, 1573=>343, 1574=>917, + 1575=>343, 1576=>1005, 1577=>590, 1578=>1005, 1579=>1005, 1580=>721, 1581=>721, 1582=>721, 1583=>513, 1584=>513, 1585=>576, 1586=>576, 1587=>1380, 1588=>1380, 1589=>1345, 1590=>1345, + 1591=>1039, 1592=>1039, 1593=>683, 1594=>683, 1600=>342, 1601=>1162, 1602=>894, 1603=>917, 1604=>868, 1605=>733, 1606=>854, 1607=>590, 1608=>622, 1609=>917, 1610=>917, 1611=>0, + 1612=>0, 1613=>0, 1614=>0, 1615=>0, 1616=>0, 1617=>0, 1618=>0, 1619=>0, 1620=>0, 1621=>0, 1626=>500, 1632=>610, 1633=>610, 1634=>610, 1635=>610, 1636=>610, + 1637=>610, 1638=>610, 1639=>610, 1640=>610, 1641=>610, 1642=>610, 1643=>374, 1644=>380, 1645=>545, 1646=>1005, 1647=>894, 1652=>292, 1657=>1005, 1658=>1005, 1659=>1005, 1660=>1005, + 1661=>1005, 1662=>1005, 1663=>1005, 1664=>1005, 1665=>721, 1666=>721, 1667=>721, 1668=>721, 1669=>721, 1670=>721, 1671=>721, 1681=>576, 1682=>576, 1685=>681, 1688=>576, 1697=>1162, + 1700=>1162, 1702=>1162, 1705=>1024, 1711=>1024, 1717=>868, 1722=>854, 1727=>721, 1734=>622, 1740=>917, 1742=>917, 1749=>590, 1776=>610, 1777=>610, 1778=>610, 1779=>610, 1780=>610, + 1781=>610, 1782=>610, 1783=>610, 1784=>610, 1785=>610, 3647=>743, 3713=>790, 3714=>748, 3716=>749, 3719=>569, 3720=>742, 3722=>744, 3725=>761, 3732=>706, 3733=>704, 3734=>747, + 3735=>819, 3737=>730, 3738=>727, 3739=>727, 3740=>922, 3741=>827, 3742=>866, 3743=>866, 3745=>836, 3746=>761, 3747=>770, 3749=>769, 3751=>713, 3754=>827, 3755=>1031, 3757=>724, + 3758=>784, 3759=>934, 3760=>688, 3761=>0, 3762=>610, 3763=>610, 3764=>0, 3765=>0, 3766=>0, 3767=>0, 3768=>0, 3769=>0, 3771=>0, 3772=>0, 3773=>670, 3776=>516, + 3777=>860, 3778=>516, 3779=>650, 3780=>632, 3782=>759, 3784=>0, 3785=>0, 3786=>0, 3787=>0, 3788=>0, 3789=>0, 3804=>1363, 3805=>1363, 5121=>774, 5122=>774, 5123=>774, + 5124=>774, 5125=>905, 5126=>905, 5127=>905, 5129=>905, 5130=>905, 5131=>905, 5132=>1018, 5133=>1009, 5134=>1018, 5135=>1009, 5136=>1018, 5137=>1009, 5138=>1149, 5139=>1140, 5140=>1149, + 5141=>1140, 5142=>905, 5143=>1149, 5144=>1142, 5145=>1149, 5146=>1142, 5147=>905, 5149=>310, 5150=>529, 5151=>425, 5152=>425, 5153=>395, 5154=>395, 5155=>395, 5156=>395, 5157=>564, + 5158=>470, 5159=>310, 5160=>395, 5161=>395, 5162=>395, 5163=>1213, 5164=>986, 5165=>1216, 5166=>1297, 5167=>774, 5168=>774, 5169=>774, 5170=>774, 5171=>886, 5172=>886, 5173=>886, + 5175=>886, 5176=>886, 5177=>886, 5178=>1018, 5179=>1009, 5180=>1018, 5181=>1009, 5182=>1018, 5183=>1009, 5184=>1149, 5185=>1140, 5186=>1149, 5187=>1140, 5188=>1149, 5189=>1142, 5190=>1149, + 5191=>1142, 5192=>886, 5193=>576, 5194=>229, 5196=>812, 5197=>812, 5198=>812, 5199=>812, 5200=>815, 5201=>815, 5202=>815, 5204=>815, 5205=>815, 5206=>815, 5207=>1056, 5208=>1048, + 5209=>1056, 5210=>1048, 5211=>1056, 5212=>1048, 5213=>1060, 5214=>1054, 5215=>1060, 5216=>1054, 5217=>1060, 5218=>1052, 5219=>1060, 5220=>1052, 5221=>1060, 5222=>483, 5223=>1005, 5224=>1005, + 5225=>1023, 5226=>1017, 5227=>743, 5228=>743, 5229=>743, 5230=>743, 5231=>743, 5232=>755, 5233=>743, 5234=>743, 5235=>743, 5236=>1029, 5237=>975, 5238=>980, 5239=>975, 5240=>980, + 5241=>975, 5242=>1029, 5243=>975, 5244=>1029, 5245=>975, 5246=>980, 5247=>975, 5248=>980, 5249=>975, 5250=>980, 5251=>501, 5252=>501, 5253=>938, 5254=>938, 5255=>938, 5256=>938, + 5257=>743, 5258=>743, 5259=>743, 5260=>743, 5261=>743, 5262=>755, 5263=>743, 5264=>743, 5265=>743, 5266=>1029, 5267=>975, 5268=>1029, 5269=>975, 5270=>1029, 5271=>975, 5272=>1029, + 5273=>975, 5274=>1029, 5275=>975, 5276=>1029, 5277=>975, 5278=>1029, 5279=>975, 5280=>1029, 5281=>501, 5282=>501, 5283=>626, 5284=>626, 5285=>626, 5286=>626, 5287=>626, 5288=>667, + 5289=>626, 5290=>626, 5291=>626, 5292=>881, 5293=>854, 5294=>863, 5295=>874, 5296=>863, 5297=>874, 5298=>881, 5299=>874, 5300=>881, 5301=>874, 5302=>863, 5303=>874, 5304=>863, + 5305=>874, 5306=>863, 5307=>436, 5308=>548, 5309=>436, 5312=>988, 5313=>988, 5314=>988, 5315=>988, 5316=>931, 5317=>931, 5318=>931, 5319=>931, 5320=>931, 5321=>1238, 5322=>1247, + 5323=>1200, 5324=>1228, 5325=>1200, 5326=>1228, 5327=>931, 5328=>660, 5329=>497, 5330=>660, 5331=>988, 5332=>988, 5333=>988, 5334=>988, 5335=>931, 5336=>931, 5337=>931, 5338=>931, + 5339=>931, 5340=>1231, 5341=>1247, 5342=>1283, 5343=>1228, 5344=>1283, 5345=>1228, 5346=>1228, 5347=>1214, 5348=>1228, 5349=>1214, 5350=>1283, 5351=>1228, 5352=>1283, 5353=>1228, 5354=>660, + 5356=>886, 5357=>730, 5358=>730, 5359=>730, 5360=>730, 5361=>730, 5362=>755, 5363=>730, 5364=>730, 5365=>730, 5366=>998, 5367=>958, 5368=>967, 5369=>989, 5370=>967, 5371=>989, + 5372=>998, 5373=>958, 5374=>998, 5375=>958, 5376=>967, 5377=>989, 5378=>967, 5379=>989, 5380=>967, 5381=>493, 5382=>460, 5383=>493, 5392=>923, 5393=>923, 5394=>923, 5395=>1136, + 5396=>1136, 5397=>1136, 5398=>1136, 5399=>1209, 5400=>1202, 5401=>1209, 5402=>1202, 5403=>1209, 5404=>1202, 5405=>1431, 5406=>1420, 5407=>1431, 5408=>1420, 5409=>1431, 5410=>1420, 5411=>1431, + 5412=>1420, 5413=>746, 5414=>776, 5415=>776, 5416=>776, 5417=>776, 5418=>776, 5419=>776, 5420=>776, 5421=>776, 5422=>776, 5423=>1003, 5424=>1003, 5425=>1013, 5426=>996, 5427=>1013, + 5428=>996, 5429=>1003, 5430=>1003, 5431=>1003, 5432=>1003, 5433=>1013, 5434=>996, 5435=>1013, 5436=>996, 5437=>1013, 5438=>495, 5440=>395, 5441=>510, 5442=>1033, 5443=>1033, 5444=>976, + 5445=>976, 5446=>976, 5447=>976, 5448=>733, 5449=>733, 5450=>733, 5451=>733, 5452=>733, 5453=>733, 5454=>1003, 5455=>959, 5456=>495, 5458=>886, 5459=>774, 5460=>774, 5461=>774, + 5462=>774, 5463=>928, 5464=>928, 5465=>928, 5466=>928, 5467=>1172, 5468=>1142, 5469=>602, 5470=>812, 5471=>812, 5472=>812, 5473=>812, 5474=>812, 5475=>812, 5476=>815, 5477=>815, + 5478=>815, 5479=>815, 5480=>1060, 5481=>1052, 5482=>548, 5492=>977, 5493=>977, 5494=>977, 5495=>977, 5496=>977, 5497=>977, 5498=>977, 5499=>618, 5500=>837, 5501=>510, 5502=>1238, + 5503=>1238, 5504=>1238, 5505=>1238, 5506=>1238, 5507=>1238, 5508=>1238, 5509=>989, 5514=>977, 5515=>977, 5516=>977, 5517=>977, 5518=>1591, 5519=>1591, 5520=>1591, 5521=>1295, 5522=>1295, + 5523=>1591, 5524=>1591, 5525=>848, 5526=>1273, 5536=>988, 5537=>988, 5538=>931, 5539=>931, 5540=>931, 5541=>931, 5542=>660, 5543=>776, 5544=>776, 5545=>776, 5546=>776, 5547=>776, + 5548=>776, 5549=>776, 5550=>495, 5551=>743, 5598=>830, 5601=>830, 5702=>496, 5703=>496, 5742=>413, 5743=>1238, 5744=>1591, 5745=>2016, 5746=>2016, 5747=>1720, 5748=>1678, 5749=>2016, + 5750=>2016, 7424=>652, 7425=>833, 7426=>1048, 7427=>608, 7428=>593, 7429=>676, 7430=>676, 7431=>559, 7432=>557, 7433=>343, 7434=>494, 7435=>665, 7436=>539, 7437=>817, 7438=>701, + 7439=>687, 7440=>593, 7441=>660, 7442=>660, 7443=>660, 7444=>1094, 7446=>687, 7447=>687, 7448=>556, 7449=>642, 7450=>642, 7451=>580, 7452=>634, 7453=>737, 7454=>948, 7455=>695, + 7456=>652, 7457=>924, 7458=>582, 7459=>646, 7462=>539, 7463=>652, 7464=>691, 7465=>556, 7466=>781, 7467=>732, 7468=>487, 7469=>683, 7470=>480, 7472=>523, 7473=>430, 7474=>430, + 7475=>517, 7476=>527, 7477=>234, 7478=>234, 7479=>488, 7480=>401, 7481=>626, 7482=>527, 7483=>527, 7484=>535, 7485=>509, 7486=>461, 7487=>485, 7488=>430, 7489=>511, 7490=>695, + 7491=>458, 7492=>458, 7493=>479, 7494=>712, 7495=>479, 7496=>479, 7497=>479, 7498=>479, 7499=>386, 7500=>386, 7501=>479, 7502=>219, 7503=>487, 7504=>664, 7505=>456, 7506=>488, + 7507=>414, 7508=>488, 7509=>488, 7510=>479, 7511=>388, 7512=>456, 7513=>462, 7514=>664, 7515=>501, 7517=>451, 7518=>429, 7519=>433, 7520=>493, 7521=>406, 7522=>219, 7523=>315, + 7524=>456, 7525=>501, 7526=>451, 7527=>429, 7528=>433, 7529=>493, 7530=>406, 7543=>716, 7544=>527, 7547=>545, 7557=>514, 7579=>479, 7580=>414, 7581=>414, 7582=>488, 7583=>386, + 7584=>377, 7585=>348, 7586=>479, 7587=>456, 7588=>347, 7589=>281, 7590=>347, 7591=>347, 7592=>431, 7593=>326, 7594=>330, 7595=>370, 7596=>664, 7597=>664, 7598=>562, 7599=>562, + 7600=>448, 7601=>488, 7602=>542, 7603=>422, 7604=>396, 7605=>388, 7606=>583, 7607=>494, 7608=>399, 7609=>451, 7610=>501, 7611=>417, 7612=>523, 7613=>470, 7614=>455, 7615=>425, + 7620=>0, 7621=>0, 7622=>0, 7623=>0, 7624=>0, 7625=>0, 7680=>774, 7681=>675, 7682=>762, 7683=>716, 7684=>762, 7685=>716, 7686=>762, 7687=>716, 7688=>734, 7689=>593, + 7690=>830, 7691=>716, 7692=>830, 7693=>716, 7694=>830, 7695=>716, 7696=>830, 7697=>716, 7698=>830, 7699=>716, 7700=>683, 7701=>678, 7702=>683, 7703=>678, 7704=>683, 7705=>678, + 7706=>683, 7707=>678, 7708=>683, 7709=>678, 7710=>683, 7711=>435, 7712=>821, 7713=>716, 7714=>837, 7715=>712, 7716=>837, 7717=>712, 7718=>837, 7719=>712, 7720=>837, 7721=>712, + 7722=>837, 7723=>712, 7724=>372, 7725=>343, 7726=>372, 7727=>343, 7728=>775, 7729=>665, 7730=>775, 7731=>665, 7732=>775, 7733=>665, 7734=>637, 7735=>343, 7736=>637, 7737=>343, + 7738=>637, 7739=>343, 7740=>637, 7741=>343, 7742=>995, 7743=>1042, 7744=>995, 7745=>1042, 7746=>995, 7747=>1042, 7748=>837, 7749=>712, 7750=>837, 7751=>712, 7752=>837, 7753=>712, + 7754=>837, 7755=>712, 7756=>850, 7757=>687, 7758=>850, 7759=>687, 7760=>850, 7761=>687, 7762=>850, 7763=>687, 7764=>733, 7765=>716, 7766=>733, 7767=>716, 7768=>770, 7769=>493, + 7770=>770, 7771=>493, 7772=>770, 7773=>493, 7774=>770, 7775=>493, 7776=>720, 7777=>595, 7778=>720, 7779=>595, 7780=>720, 7781=>595, 7782=>720, 7783=>595, 7784=>720, 7785=>595, + 7786=>682, 7787=>478, 7788=>682, 7789=>478, 7790=>682, 7791=>478, 7792=>682, 7793=>478, 7794=>812, 7795=>712, 7796=>812, 7797=>712, 7798=>812, 7799=>712, 7800=>812, 7801=>712, + 7802=>812, 7803=>712, 7804=>774, 7805=>652, 7806=>774, 7807=>652, 7808=>1103, 7809=>924, 7810=>1103, 7811=>924, 7812=>1103, 7813=>924, 7814=>1103, 7815=>924, 7816=>1103, 7817=>924, + 7818=>771, 7819=>645, 7820=>771, 7821=>645, 7822=>724, 7823=>652, 7824=>725, 7825=>582, 7826=>725, 7827=>582, 7828=>725, 7829=>582, 7830=>712, 7831=>478, 7832=>924, 7833=>652, + 7834=>675, 7835=>435, 7840=>774, 7841=>675, 7842=>774, 7843=>675, 7844=>774, 7845=>675, 7846=>774, 7847=>675, 7848=>774, 7849=>675, 7850=>774, 7851=>675, 7852=>774, 7853=>675, + 7854=>774, 7855=>675, 7856=>774, 7857=>675, 7858=>774, 7859=>675, 7860=>774, 7861=>675, 7862=>774, 7863=>675, 7864=>683, 7865=>678, 7866=>683, 7867=>678, 7868=>683, 7869=>678, + 7870=>683, 7871=>678, 7872=>683, 7873=>678, 7874=>683, 7875=>678, 7876=>683, 7877=>678, 7878=>683, 7879=>678, 7880=>372, 7881=>343, 7882=>372, 7883=>343, 7884=>850, 7885=>687, + 7886=>850, 7887=>687, 7888=>850, 7889=>687, 7890=>850, 7891=>687, 7892=>850, 7893=>687, 7894=>850, 7895=>687, 7896=>850, 7897=>687, 7898=>874, 7899=>687, 7900=>874, 7901=>687, + 7902=>874, 7903=>687, 7904=>874, 7905=>687, 7906=>874, 7907=>687, 7908=>812, 7909=>712, 7910=>812, 7911=>712, 7912=>835, 7913=>712, 7914=>835, 7915=>712, 7916=>835, 7917=>712, + 7918=>835, 7919=>712, 7920=>835, 7921=>712, 7922=>724, 7923=>652, 7924=>724, 7925=>652, 7926=>724, 7927=>652, 7928=>724, 7929=>652, 7936=>687, 7937=>687, 7938=>687, 7939=>687, + 7940=>687, 7941=>687, 7942=>687, 7943=>687, 7944=>774, 7945=>774, 7946=>1041, 7947=>1043, 7948=>935, 7949=>963, 7950=>835, 7951=>859, 7952=>557, 7953=>557, 7954=>557, 7955=>557, + 7956=>557, 7957=>557, 7960=>792, 7961=>794, 7962=>1100, 7963=>1096, 7964=>1023, 7965=>1052, 7968=>712, 7969=>712, 7970=>712, 7971=>712, 7972=>712, 7973=>712, 7974=>712, 7975=>712, + 7976=>945, 7977=>951, 7978=>1250, 7979=>1250, 7980=>1180, 7981=>1206, 7982=>1054, 7983=>1063, 7984=>390, 7985=>390, 7986=>390, 7987=>390, 7988=>390, 7989=>390, 7990=>390, 7991=>390, + 7992=>483, 7993=>489, 7994=>777, 7995=>785, 7996=>712, 7997=>738, 7998=>604, 7999=>604, 8000=>687, 8001=>687, 8002=>687, 8003=>687, 8004=>687, 8005=>687, 8008=>892, 8009=>933, + 8010=>1221, 8011=>1224, 8012=>1053, 8013=>1082, 8016=>675, 8017=>675, 8018=>675, 8019=>675, 8020=>675, 8021=>675, 8022=>675, 8023=>675, 8025=>930, 8027=>1184, 8029=>1199, 8031=>1049, + 8032=>869, 8033=>869, 8034=>869, 8035=>869, 8036=>869, 8037=>869, 8038=>869, 8039=>869, 8040=>909, 8041=>958, 8042=>1246, 8043=>1251, 8044=>1076, 8045=>1105, 8046=>1028, 8047=>1076, + 8048=>687, 8049=>687, 8050=>557, 8051=>557, 8052=>712, 8053=>712, 8054=>390, 8055=>390, 8056=>687, 8057=>687, 8058=>675, 8059=>675, 8060=>869, 8061=>869, 8064=>687, 8065=>687, + 8066=>687, 8067=>687, 8068=>687, 8069=>687, 8070=>687, 8071=>687, 8072=>774, 8073=>774, 8074=>1041, 8075=>1043, 8076=>935, 8077=>963, 8078=>835, 8079=>859, 8080=>712, 8081=>712, + 8082=>712, 8083=>712, 8084=>712, 8085=>712, 8086=>712, 8087=>712, 8088=>945, 8089=>951, 8090=>1250, 8091=>1250, 8092=>1180, 8093=>1206, 8094=>1054, 8095=>1063, 8096=>869, 8097=>869, + 8098=>869, 8099=>869, 8100=>869, 8101=>869, 8102=>869, 8103=>869, 8104=>909, 8105=>958, 8106=>1246, 8107=>1251, 8108=>1076, 8109=>1105, 8110=>1028, 8111=>1076, 8112=>687, 8113=>687, + 8114=>687, 8115=>687, 8116=>687, 8118=>687, 8119=>687, 8120=>774, 8121=>774, 8122=>876, 8123=>797, 8124=>774, 8125=>500, 8126=>500, 8127=>500, 8128=>500, 8129=>500, 8130=>712, + 8131=>712, 8132=>712, 8134=>712, 8135=>712, 8136=>929, 8137=>846, 8138=>1080, 8139=>1009, 8140=>837, 8141=>500, 8142=>500, 8143=>500, 8144=>390, 8145=>390, 8146=>390, 8147=>390, + 8150=>390, 8151=>390, 8152=>372, 8153=>372, 8154=>621, 8155=>563, 8157=>500, 8158=>500, 8159=>500, 8160=>675, 8161=>675, 8162=>675, 8163=>675, 8164=>716, 8165=>716, 8166=>675, + 8167=>675, 8168=>724, 8169=>724, 8170=>1020, 8171=>980, 8172=>838, 8173=>500, 8174=>500, 8175=>500, 8178=>869, 8179=>869, 8180=>869, 8182=>869, 8183=>869, 8184=>1065, 8185=>891, + 8186=>1084, 8187=>894, 8188=>850, 8189=>500, 8190=>500, 8192=>500, 8193=>1000, 8194=>500, 8195=>1000, 8196=>330, 8197=>250, 8198=>167, 8199=>696, 8200=>380, 8201=>200, 8202=>100, + 8203=>0, 8204=>0, 8205=>0, 8206=>0, 8207=>0, 8208=>415, 8209=>415, 8210=>696, 8213=>1000, 8214=>500, 8215=>500, 8219=>380, 8223=>657, 8227=>639, 8228=>333, 8229=>667, + 8231=>348, 8234=>0, 8235=>0, 8236=>0, 8237=>0, 8238=>0, 8239=>200, 8241=>1887, 8242=>264, 8243=>447, 8244=>630, 8245=>264, 8246=>447, 8247=>630, 8248=>733, 8251=>972, + 8252=>627, 8253=>580, 8254=>500, 8255=>828, 8256=>828, 8257=>329, 8258=>1023, 8259=>500, 8260=>456, 8261=>457, 8262=>457, 8263=>1030, 8264=>829, 8265=>829, 8266=>513, 8267=>636, + 8268=>500, 8269=>500, 8270=>523, 8271=>400, 8272=>828, 8273=>523, 8274=>556, 8275=>838, 8276=>828, 8277=>838, 8278=>684, 8279=>813, 8280=>838, 8281=>838, 8282=>380, 8283=>872, + 8284=>838, 8285=>380, 8286=>380, 8287=>222, 8288=>0, 8289=>0, 8290=>0, 8291=>0, 8298=>0, 8299=>0, 8300=>0, 8301=>0, 8302=>0, 8303=>0, 8304=>438, 8305=>219, + 8308=>438, 8309=>438, 8310=>438, 8311=>438, 8312=>438, 8313=>438, 8314=>528, 8315=>528, 8316=>528, 8317=>288, 8318=>288, 8319=>456, 8320=>438, 8321=>438, 8322=>438, 8323=>438, + 8324=>438, 8325=>438, 8326=>438, 8327=>438, 8328=>438, 8329=>438, 8330=>528, 8331=>528, 8332=>528, 8333=>288, 8334=>288, 8336=>458, 8337=>479, 8338=>488, 8339=>413, 8340=>479, + 8352=>929, 8353=>696, 8354=>696, 8355=>696, 8356=>696, 8357=>1042, 8358=>837, 8359=>1518, 8360=>1205, 8361=>1103, 8362=>904, 8363=>696, 8365=>696, 8366=>682, 8367=>1392, 8368=>696, + 8369=>696, 8370=>696, 8371=>696, 8372=>859, 8373=>696, 8400=>0, 8401=>0, 8406=>0, 8407=>0, 8448=>1120, 8449=>1170, 8450=>734, 8451=>1211, 8452=>896, 8453=>1091, 8454=>1144, + 8455=>614, 8456=>698, 8457=>1086, 8459=>1073, 8460=>913, 8461=>850, 8462=>712, 8463=>712, 8464=>604, 8465=>694, 8466=>868, 8467=>472, 8468=>974, 8469=>837, 8470=>1203, 8471=>1000, + 8472=>697, 8473=>702, 8474=>850, 8475=>876, 8476=>814, 8477=>792, 8478=>896, 8479=>710, 8480=>1020, 8481=>1281, 8483=>755, 8484=>725, 8485=>578, 8486=>850, 8487=>769, 8488=>763, + 8489=>338, 8490=>775, 8491=>774, 8492=>928, 8493=>776, 8494=>854, 8495=>636, 8496=>738, 8497=>811, 8498=>683, 8499=>1193, 8500=>465, 8501=>794, 8502=>736, 8503=>503, 8504=>695, + 8505=>380, 8506=>945, 8507=>1348, 8508=>790, 8509=>737, 8510=>652, 8511=>845, 8512=>840, 8513=>775, 8514=>557, 8515=>637, 8516=>760, 8517=>830, 8518=>716, 8519=>678, 8520=>343, + 8521=>343, 8523=>872, 8526=>547, 8531=>1035, 8532=>1035, 8533=>1035, 8534=>1035, 8535=>1035, 8536=>1035, 8537=>1035, 8538=>1035, 8539=>1035, 8540=>1035, 8541=>1035, 8542=>1035, 8543=>615, + 8544=>372, 8545=>659, 8546=>945, 8547=>1099, 8548=>774, 8549=>1099, 8550=>1386, 8551=>1672, 8552=>1121, 8553=>771, 8554=>1120, 8555=>1407, 8556=>637, 8557=>734, 8558=>830, 8559=>995, + 8560=>343, 8561=>607, 8562=>872, 8563=>984, 8564=>652, 8565=>962, 8566=>1227, 8567=>1491, 8568=>969, 8569=>645, 8570=>969, 8571=>1233, 8572=>343, 8573=>593, 8574=>716, 8575=>1042, + 8576=>1289, 8577=>830, 8578=>1289, 8579=>734, 8580=>593, 8592=>838, 8593=>838, 8594=>838, 8595=>838, 8596=>838, 8597=>838, 8598=>838, 8599=>838, 8600=>838, 8601=>838, 8602=>838, + 8603=>838, 8604=>838, 8605=>838, 8606=>838, 8607=>838, 8608=>838, 8609=>838, 8610=>838, 8611=>838, 8612=>838, 8613=>838, 8614=>838, 8615=>838, 8616=>838, 8617=>838, 8618=>838, + 8619=>838, 8620=>838, 8621=>838, 8622=>838, 8623=>838, 8624=>838, 8625=>838, 8626=>838, 8627=>838, 8628=>838, 8629=>838, 8630=>838, 8631=>838, 8632=>838, 8633=>838, 8634=>838, + 8635=>838, 8636=>838, 8637=>838, 8638=>838, 8639=>838, 8640=>838, 8641=>838, 8642=>838, 8643=>838, 8644=>838, 8645=>838, 8646=>838, 8647=>838, 8648=>838, 8649=>838, 8650=>838, + 8651=>838, 8652=>838, 8653=>838, 8654=>838, 8655=>838, 8656=>838, 8657=>838, 8658=>838, 8659=>838, 8660=>838, 8661=>838, 8662=>838, 8663=>838, 8664=>838, 8665=>838, 8666=>838, + 8667=>838, 8668=>838, 8669=>838, 8670=>838, 8671=>838, 8672=>838, 8673=>838, 8674=>838, 8675=>838, 8676=>838, 8677=>838, 8678=>838, 8679=>838, 8680=>838, 8681=>838, 8682=>838, + 8683=>838, 8684=>838, 8685=>838, 8686=>838, 8687=>838, 8688=>838, 8689=>838, 8690=>838, 8691=>838, 8692=>838, 8693=>838, 8694=>838, 8695=>838, 8696=>838, 8697=>838, 8698=>838, + 8699=>838, 8700=>838, 8701=>838, 8702=>838, 8703=>838, 8704=>774, 8705=>696, 8706=>544, 8707=>683, 8708=>683, 8709=>856, 8710=>697, 8711=>697, 8712=>896, 8713=>896, 8714=>750, + 8715=>896, 8716=>896, 8717=>750, 8718=>636, 8719=>787, 8720=>787, 8721=>718, 8722=>838, 8723=>838, 8724=>696, 8725=>167, 8726=>696, 8727=>838, 8728=>626, 8729=>380, 8730=>667, + 8731=>667, 8732=>667, 8733=>669, 8734=>833, 8735=>838, 8736=>896, 8737=>896, 8738=>838, 8739=>500, 8740=>500, 8741=>500, 8742=>500, 8743=>812, 8744=>812, 8745=>812, 8746=>812, + 8747=>610, 8748=>929, 8749=>1295, 8750=>563, 8751=>977, 8752=>1313, 8753=>563, 8754=>563, 8755=>563, 8756=>696, 8757=>696, 8758=>294, 8759=>696, 8760=>838, 8761=>838, 8762=>838, + 8763=>838, 8764=>838, 8765=>838, 8766=>838, 8767=>838, 8768=>375, 8769=>838, 8770=>838, 8771=>838, 8772=>838, 8773=>838, 8774=>838, 8775=>838, 8776=>838, 8777=>838, 8778=>838, + 8779=>838, 8780=>838, 8781=>838, 8782=>838, 8783=>838, 8784=>838, 8785=>838, 8786=>838, 8787=>838, 8788=>1063, 8789=>1063, 8790=>838, 8791=>838, 8792=>838, 8793=>838, 8794=>838, + 8795=>838, 8796=>838, 8797=>838, 8798=>838, 8799=>838, 8800=>838, 8801=>838, 8802=>838, 8803=>838, 8804=>838, 8805=>838, 8806=>838, 8807=>838, 8808=>841, 8809=>841, 8810=>1047, + 8811=>1047, 8812=>500, 8813=>838, 8814=>838, 8815=>838, 8816=>838, 8817=>838, 8818=>838, 8819=>838, 8820=>838, 8821=>838, 8822=>838, 8823=>838, 8824=>838, 8825=>838, 8826=>838, + 8827=>838, 8828=>838, 8829=>838, 8830=>838, 8831=>838, 8832=>838, 8833=>838, 8834=>838, 8835=>838, 8836=>838, 8837=>838, 8838=>838, 8839=>838, 8840=>838, 8841=>838, 8842=>838, + 8843=>838, 8844=>812, 8845=>812, 8846=>812, 8847=>838, 8848=>838, 8849=>838, 8850=>838, 8851=>754, 8852=>754, 8853=>838, 8854=>838, 8855=>838, 8856=>838, 8857=>838, 8858=>838, + 8859=>838, 8860=>838, 8861=>838, 8862=>838, 8863=>838, 8864=>838, 8865=>838, 8866=>914, 8867=>914, 8868=>914, 8869=>914, 8870=>542, 8871=>542, 8872=>914, 8873=>914, 8874=>914, + 8875=>914, 8876=>914, 8877=>914, 8878=>914, 8879=>914, 8882=>838, 8883=>838, 8884=>838, 8885=>838, 8886=>1000, 8887=>1000, 8888=>838, 8889=>838, 8890=>542, 8891=>812, 8892=>812, + 8893=>812, 8896=>843, 8897=>843, 8898=>843, 8899=>843, 8900=>494, 8901=>380, 8902=>626, 8904=>1000, 8905=>1000, 8906=>1000, 8907=>1000, 8908=>1000, 8909=>838, 8918=>838, 8919=>838, + 8920=>1422, 8921=>1422, 8922=>838, 8923=>838, 8924=>838, 8925=>838, 8926=>838, 8927=>838, 8928=>838, 8929=>838, 8930=>838, 8931=>838, 8932=>838, 8933=>838, 8934=>838, 8935=>838, + 8936=>838, 8937=>838, 8938=>838, 8939=>838, 8940=>838, 8941=>838, 8946=>1158, 8947=>896, 8948=>750, 8949=>896, 8950=>896, 8951=>750, 8952=>896, 8953=>896, 8954=>1158, 8955=>896, + 8956=>750, 8957=>896, 8958=>750, 8959=>896, 8962=>716, 8966=>917, 8968=>457, 8969=>457, 8970=>457, 8971=>457, 8976=>838, 8977=>539, 8984=>928, 8985=>838, 8992=>610, 8993=>610, + 8997=>1000, 9000=>1443, 9085=>863, 9115=>500, 9116=>500, 9117=>500, 9118=>500, 9119=>500, 9120=>500, 9121=>500, 9122=>500, 9123=>500, 9124=>500, 9125=>500, 9126=>500, 9127=>750, + 9128=>750, 9129=>750, 9130=>750, 9131=>750, 9132=>750, 9133=>750, 9134=>610, 9166=>838, 9167=>945, 9250=>716, 9251=>716, 9312=>847, 9313=>847, 9314=>847, 9315=>847, 9316=>847, + 9317=>847, 9318=>847, 9319=>847, 9320=>847, 9321=>847, 9600=>769, 9601=>769, 9602=>769, 9603=>769, 9604=>769, 9605=>769, 9606=>769, 9607=>769, 9608=>769, 9609=>769, 9610=>769, + 9611=>769, 9612=>769, 9613=>769, 9614=>769, 9615=>769, 9616=>769, 9617=>769, 9618=>769, 9619=>769, 9620=>769, 9621=>769, 9622=>769, 9623=>769, 9624=>769, 9625=>769, 9626=>769, + 9627=>769, 9628=>769, 9629=>769, 9630=>769, 9631=>769, 9632=>945, 9633=>945, 9634=>945, 9635=>945, 9636=>945, 9637=>945, 9638=>945, 9639=>945, 9640=>945, 9641=>945, 9642=>678, + 9643=>678, 9644=>945, 9645=>945, 9646=>550, 9647=>550, 9648=>769, 9649=>769, 9650=>769, 9651=>769, 9652=>502, 9653=>502, 9654=>769, 9655=>769, 9656=>502, 9657=>502, 9658=>769, + 9659=>769, 9660=>769, 9661=>769, 9662=>502, 9663=>502, 9664=>769, 9665=>769, 9666=>502, 9667=>502, 9668=>769, 9669=>769, 9670=>769, 9671=>769, 9672=>769, 9673=>873, 9674=>494, + 9675=>873, 9676=>873, 9677=>873, 9678=>873, 9679=>873, 9680=>873, 9681=>873, 9682=>873, 9683=>873, 9684=>873, 9685=>873, 9686=>527, 9687=>527, 9688=>840, 9689=>970, 9690=>970, + 9691=>970, 9692=>387, 9693=>387, 9694=>387, 9695=>387, 9696=>769, 9697=>769, 9698=>769, 9699=>769, 9700=>769, 9701=>769, 9702=>639, 9703=>945, 9704=>945, 9705=>945, 9706=>945, + 9707=>945, 9708=>769, 9709=>769, 9710=>769, 9711=>1119, 9712=>945, 9713=>945, 9714=>945, 9715=>945, 9716=>873, 9717=>873, 9718=>873, 9719=>873, 9720=>769, 9721=>769, 9722=>769, + 9723=>830, 9724=>830, 9725=>732, 9726=>732, 9727=>769, 9728=>896, 9729=>1000, 9730=>896, 9731=>896, 9732=>896, 9733=>896, 9734=>896, 9735=>573, 9736=>896, 9737=>896, 9738=>888, + 9739=>888, 9740=>671, 9741=>1013, 9742=>1246, 9743=>1250, 9744=>896, 9745=>896, 9746=>896, 9747=>532, 9748=>896, 9749=>896, 9750=>896, 9751=>896, 9752=>896, 9753=>896, 9754=>896, + 9755=>896, 9756=>896, 9757=>609, 9758=>896, 9759=>609, 9760=>896, 9761=>896, 9762=>896, 9763=>896, 9764=>669, 9765=>746, 9766=>649, 9767=>784, 9768=>545, 9769=>896, 9770=>896, + 9771=>896, 9772=>710, 9773=>896, 9774=>896, 9775=>896, 9776=>896, 9777=>896, 9778=>896, 9779=>896, 9780=>896, 9781=>896, 9782=>896, 9783=>896, 9784=>896, 9785=>896, 9786=>896, + 9787=>896, 9788=>896, 9789=>896, 9790=>896, 9791=>614, 9792=>731, 9793=>731, 9794=>896, 9795=>896, 9796=>896, 9797=>896, 9798=>896, 9799=>896, 9800=>896, 9801=>896, 9802=>896, + 9803=>896, 9804=>896, 9805=>896, 9806=>896, 9807=>896, 9808=>896, 9809=>896, 9810=>896, 9811=>896, 9812=>896, 9813=>896, 9814=>896, 9815=>896, 9816=>896, 9817=>896, 9818=>896, + 9819=>896, 9820=>896, 9821=>896, 9822=>896, 9823=>896, 9824=>896, 9825=>896, 9826=>896, 9827=>896, 9828=>896, 9829=>896, 9830=>896, 9831=>896, 9832=>896, 9833=>472, 9834=>638, + 9835=>896, 9836=>896, 9837=>472, 9838=>357, 9839=>484, 9840=>748, 9841=>766, 9842=>896, 9843=>896, 9844=>896, 9845=>896, 9846=>896, 9847=>896, 9848=>896, 9849=>896, 9850=>896, + 9851=>896, 9852=>896, 9853=>896, 9854=>896, 9855=>896, 9856=>869, 9857=>869, 9858=>869, 9859=>869, 9860=>869, 9861=>869, 9862=>896, 9863=>896, 9864=>896, 9865=>896, 9866=>896, + 9867=>896, 9868=>896, 9869=>896, 9870=>896, 9871=>896, 9872=>896, 9873=>896, 9874=>896, 9875=>896, 9876=>896, 9877=>541, 9878=>896, 9879=>896, 9880=>896, 9881=>896, 9882=>896, + 9883=>896, 9884=>896, 9888=>896, 9889=>702, 9890=>838, 9891=>838, 9892=>838, 9893=>838, 9894=>838, 9895=>838, 9896=>838, 9897=>838, 9898=>838, 9899=>838, 9900=>838, 9901=>838, + 9902=>838, 9903=>838, 9904=>844, 9905=>838, 9906=>731, 9985=>838, 9986=>838, 9987=>838, 9988=>838, 9990=>838, 9991=>838, 9992=>838, 9993=>838, 9996=>838, 9997=>838, 9998=>838, + 9999=>838, 10000=>838, 10001=>838, 10002=>838, 10003=>838, 10004=>838, 10005=>838, 10006=>838, 10007=>838, 10008=>838, 10009=>838, 10010=>838, 10011=>838, 10012=>838, 10013=>838, 10014=>838, + 10015=>838, 10016=>838, 10017=>838, 10018=>838, 10019=>838, 10020=>838, 10021=>838, 10022=>838, 10023=>838, 10025=>838, 10026=>838, 10027=>838, 10028=>838, 10029=>838, 10030=>838, 10031=>838, + 10032=>838, 10033=>838, 10034=>838, 10035=>838, 10036=>838, 10037=>838, 10038=>838, 10039=>838, 10040=>838, 10041=>838, 10042=>838, 10043=>838, 10044=>838, 10045=>838, 10046=>838, 10047=>838, + 10048=>838, 10049=>838, 10050=>838, 10051=>838, 10052=>838, 10053=>838, 10054=>838, 10055=>838, 10056=>838, 10057=>838, 10058=>838, 10059=>838, 10061=>896, 10063=>896, 10064=>896, 10065=>896, + 10066=>896, 10070=>896, 10072=>838, 10073=>838, 10074=>838, 10075=>347, 10076=>347, 10077=>587, 10078=>587, 10081=>838, 10082=>838, 10083=>838, 10084=>838, 10085=>838, 10086=>838, 10087=>838, + 10088=>838, 10089=>838, 10090=>838, 10091=>838, 10092=>838, 10093=>838, 10094=>838, 10095=>838, 10096=>838, 10097=>838, 10098=>838, 10099=>838, 10100=>838, 10101=>838, 10102=>847, 10103=>847, + 10104=>847, 10105=>847, 10106=>847, 10107=>847, 10108=>847, 10109=>847, 10110=>847, 10111=>847, 10112=>838, 10113=>838, 10114=>838, 10115=>838, 10116=>838, 10117=>838, 10118=>838, 10119=>838, + 10120=>838, 10121=>838, 10122=>838, 10123=>838, 10124=>838, 10125=>838, 10126=>838, 10127=>838, 10128=>838, 10129=>838, 10130=>838, 10131=>838, 10132=>838, 10136=>838, 10137=>838, 10138=>838, + 10139=>838, 10140=>838, 10141=>838, 10142=>838, 10143=>838, 10144=>838, 10145=>838, 10146=>838, 10147=>838, 10148=>838, 10149=>838, 10150=>838, 10151=>838, 10152=>838, 10153=>838, 10154=>838, + 10155=>838, 10156=>838, 10157=>838, 10158=>838, 10159=>838, 10161=>838, 10162=>838, 10163=>838, 10164=>838, 10165=>838, 10166=>838, 10167=>838, 10168=>838, 10169=>838, 10170=>838, 10171=>838, + 10172=>838, 10173=>838, 10174=>838, 10208=>494, 10214=>487, 10215=>487, 10216=>457, 10217=>457, 10218=>721, 10219=>721, 10224=>838, 10225=>838, 10226=>838, 10227=>838, 10228=>1157, 10229=>1434, + 10230=>1434, 10231=>1434, 10232=>1434, 10233=>1434, 10234=>1434, 10235=>1434, 10236=>1434, 10237=>1434, 10238=>1434, 10239=>1434, 10240=>781, 10241=>781, 10242=>781, 10243=>781, 10244=>781, 10245=>781, + 10246=>781, 10247=>781, 10248=>781, 10249=>781, 10250=>781, 10251=>781, 10252=>781, 10253=>781, 10254=>781, 10255=>781, 10256=>781, 10257=>781, 10258=>781, 10259=>781, 10260=>781, 10261=>781, + 10262=>781, 10263=>781, 10264=>781, 10265=>781, 10266=>781, 10267=>781, 10268=>781, 10269=>781, 10270=>781, 10271=>781, 10272=>781, 10273=>781, 10274=>781, 10275=>781, 10276=>781, 10277=>781, + 10278=>781, 10279=>781, 10280=>781, 10281=>781, 10282=>781, 10283=>781, 10284=>781, 10285=>781, 10286=>781, 10287=>781, 10288=>781, 10289=>781, 10290=>781, 10291=>781, 10292=>781, 10293=>781, + 10294=>781, 10295=>781, 10296=>781, 10297=>781, 10298=>781, 10299=>781, 10300=>781, 10301=>781, 10302=>781, 10303=>781, 10304=>781, 10305=>781, 10306=>781, 10307=>781, 10308=>781, 10309=>781, + 10310=>781, 10311=>781, 10312=>781, 10313=>781, 10314=>781, 10315=>781, 10316=>781, 10317=>781, 10318=>781, 10319=>781, 10320=>781, 10321=>781, 10322=>781, 10323=>781, 10324=>781, 10325=>781, + 10326=>781, 10327=>781, 10328=>781, 10329=>781, 10330=>781, 10331=>781, 10332=>781, 10333=>781, 10334=>781, 10335=>781, 10336=>781, 10337=>781, 10338=>781, 10339=>781, 10340=>781, 10341=>781, + 10342=>781, 10343=>781, 10344=>781, 10345=>781, 10346=>781, 10347=>781, 10348=>781, 10349=>781, 10350=>781, 10351=>781, 10352=>781, 10353=>781, 10354=>781, 10355=>781, 10356=>781, 10357=>781, + 10358=>781, 10359=>781, 10360=>781, 10361=>781, 10362=>781, 10363=>781, 10364=>781, 10365=>781, 10366=>781, 10367=>781, 10368=>781, 10369=>781, 10370=>781, 10371=>781, 10372=>781, 10373=>781, + 10374=>781, 10375=>781, 10376=>781, 10377=>781, 10378=>781, 10379=>781, 10380=>781, 10381=>781, 10382=>781, 10383=>781, 10384=>781, 10385=>781, 10386=>781, 10387=>781, 10388=>781, 10389=>781, + 10390=>781, 10391=>781, 10392=>781, 10393=>781, 10394=>781, 10395=>781, 10396=>781, 10397=>781, 10398=>781, 10399=>781, 10400=>781, 10401=>781, 10402=>781, 10403=>781, 10404=>781, 10405=>781, + 10406=>781, 10407=>781, 10408=>781, 10409=>781, 10410=>781, 10411=>781, 10412=>781, 10413=>781, 10414=>781, 10415=>781, 10416=>781, 10417=>781, 10418=>781, 10419=>781, 10420=>781, 10421=>781, + 10422=>781, 10423=>781, 10424=>781, 10425=>781, 10426=>781, 10427=>781, 10428=>781, 10429=>781, 10430=>781, 10431=>781, 10432=>781, 10433=>781, 10434=>781, 10435=>781, 10436=>781, 10437=>781, + 10438=>781, 10439=>781, 10440=>781, 10441=>781, 10442=>781, 10443=>781, 10444=>781, 10445=>781, 10446=>781, 10447=>781, 10448=>781, 10449=>781, 10450=>781, 10451=>781, 10452=>781, 10453=>781, + 10454=>781, 10455=>781, 10456=>781, 10457=>781, 10458=>781, 10459=>781, 10460=>781, 10461=>781, 10462=>781, 10463=>781, 10464=>781, 10465=>781, 10466=>781, 10467=>781, 10468=>781, 10469=>781, + 10470=>781, 10471=>781, 10472=>781, 10473=>781, 10474=>781, 10475=>781, 10476=>781, 10477=>781, 10478=>781, 10479=>781, 10480=>781, 10481=>781, 10482=>781, 10483=>781, 10484=>781, 10485=>781, + 10486=>781, 10487=>781, 10488=>781, 10489=>781, 10490=>781, 10491=>781, 10492=>781, 10493=>781, 10494=>781, 10495=>781, 10502=>838, 10503=>838, 10506=>838, 10507=>838, 10560=>838, 10561=>838, + 10702=>838, 10703=>1046, 10704=>1046, 10705=>1000, 10706=>1000, 10707=>1000, 10708=>1000, 10709=>1000, 10731=>494, 10752=>1000, 10753=>1000, 10754=>1000, 10764=>1661, 10765=>563, 10766=>563, 10767=>563, + 10768=>563, 10769=>563, 10770=>563, 10771=>563, 10772=>563, 10773=>563, 10774=>563, 10775=>563, 10776=>563, 10777=>563, 10778=>563, 10779=>563, 10780=>563, 10877=>838, 10878=>838, 10879=>838, + 10880=>838, 10881=>838, 10882=>838, 10883=>838, 10884=>838, 10885=>838, 10886=>838, 10887=>838, 10888=>838, 10889=>838, 10890=>838, 10891=>838, 10892=>838, 10893=>838, 10894=>838, 10895=>838, + 10896=>838, 10897=>838, 10898=>838, 10899=>838, 10900=>838, 10901=>838, 10902=>838, 10903=>838, 10904=>838, 10905=>838, 10906=>838, 10907=>838, 10908=>838, 10909=>838, 10910=>838, 10911=>838, + 10912=>838, 10926=>838, 10927=>838, 10928=>838, 10929=>838, 10930=>838, 10931=>838, 10932=>838, 10933=>838, 10934=>838, 10935=>838, 10936=>838, 10937=>838, 10938=>838, 11001=>838, 11002=>838, + 11008=>838, 11009=>838, 11010=>838, 11011=>838, 11012=>838, 11013=>838, 11014=>838, 11015=>838, 11016=>838, 11017=>838, 11018=>838, 11019=>838, 11020=>838, 11021=>838, 11022=>838, 11023=>838, + 11024=>838, 11025=>838, 11026=>945, 11027=>945, 11028=>945, 11029=>945, 11030=>769, 11031=>769, 11032=>769, 11033=>769, 11034=>945, 11040=>869, 11041=>873, 11042=>873, 11043=>873, 11360=>637, + 11361=>360, 11362=>637, 11363=>733, 11364=>770, 11365=>675, 11366=>478, 11367=>956, 11368=>712, 11369=>775, 11370=>665, 11371=>725, 11372=>582, 11380=>652, 11381=>649, 11382=>516, 11383=>782, + 61960=>860, 62047=>720, 63173=>687, 64256=>810, 64257=>741, 64258=>741, 64259=>1115, 64260=>1116, 64261=>808, 64262=>1020, 64275=>1388, 64276=>1384, 64277=>1378, 64278=>1384, 64279=>1713, 64285=>372, + 64287=>692, 64288=>720, 64297=>838, 64298=>963, 64299=>963, 64300=>963, 64301=>963, 64302=>751, 64303=>751, 64304=>751, 64305=>731, 64306=>537, 64307=>684, 64308=>778, 64309=>467, 64310=>521, + 64312=>770, 64313=>467, 64314=>778, 64315=>750, 64316=>718, 64318=>856, 64320=>532, 64321=>855, 64323=>802, 64324=>777, 64326=>751, 64327=>803, 64328=>778, 64329=>963, 64330=>822, 64331=>372, + 64332=>731, 64333=>754, 64334=>777, 64338=>1005, 64339=>1059, 64340=>375, 64341=>408, 64342=>1005, 64343=>1059, 64344=>375, 64345=>408, 64346=>1005, 64347=>1059, 64348=>375, 64349=>408, 64350=>1005, + 64351=>1059, 64352=>375, 64353=>408, 64354=>1005, 64355=>1059, 64356=>375, 64357=>408, 64358=>1005, 64359=>1059, 64360=>375, 64361=>408, 64362=>1162, 64363=>1191, 64364=>655, 64365=>720, 64366=>1162, + 64367=>1191, 64368=>655, 64369=>720, 64370=>721, 64371=>721, 64372=>721, 64373=>721, 64374=>721, 64375=>721, 64376=>721, 64377=>721, 64378=>721, 64379=>721, 64380=>721, 64381=>721, 64382=>721, + 64383=>721, 64384=>721, 64385=>721, 64394=>576, 64395=>622, 64396=>576, 64397=>622, 64398=>1024, 64399=>1024, 64400=>582, 64401=>582, 64402=>1024, 64403=>1024, 64404=>582, 64405=>582, 64414=>854, + 64415=>900, 64473=>622, 64474=>627, 64488=>375, 64489=>408, 64508=>917, 64509=>1012, 64510=>375, 64511=>408, 65024=>0, 65025=>0, 65026=>0, 65027=>0, 65028=>0, 65029=>0, 65030=>0, + 65031=>0, 65032=>0, 65033=>0, 65034=>0, 65035=>0, 65036=>0, 65037=>0, 65038=>0, 65039=>0, 65136=>342, 65137=>342, 65138=>342, 65139=>346, 65140=>342, 65142=>342, 65143=>342, + 65144=>342, 65145=>342, 65146=>342, 65147=>342, 65148=>342, 65149=>342, 65150=>342, 65151=>342, 65152=>511, 65153=>343, 65154=>375, 65155=>343, 65156=>375, 65157=>622, 65158=>627, 65159=>343, + 65160=>375, 65161=>917, 65162=>917, 65163=>375, 65164=>408, 65165=>343, 65166=>375, 65167=>1005, 65168=>1059, 65169=>375, 65170=>408, 65171=>590, 65172=>606, 65173=>1005, 65174=>1059, 65175=>375, + 65176=>408, 65177=>1005, 65178=>1059, 65179=>375, 65180=>408, 65181=>721, 65182=>721, 65183=>721, 65184=>721, 65185=>721, 65186=>721, 65187=>721, 65188=>721, 65189=>721, 65190=>721, 65191=>721, + 65192=>721, 65193=>513, 65194=>578, 65195=>513, 65196=>578, 65197=>576, 65198=>622, 65199=>576, 65200=>622, 65201=>1380, 65202=>1414, 65203=>983, 65204=>1018, 65205=>1380, 65206=>1414, 65207=>983, + 65208=>1018, 65209=>1345, 65210=>1364, 65211=>966, 65212=>985, 65213=>1345, 65214=>1364, 65215=>966, 65216=>985, 65217=>1039, 65218=>1071, 65219=>942, 65220=>974, 65221=>1039, 65222=>1071, 65223=>942, + 65224=>974, 65225=>683, 65226=>683, 65227=>683, 65228=>564, 65229=>683, 65230=>683, 65231=>683, 65232=>564, 65233=>1162, 65234=>1191, 65235=>655, 65236=>720, 65237=>894, 65238=>901, 65239=>655, + 65240=>720, 65241=>917, 65242=>931, 65243=>582, 65244=>582, 65245=>868, 65246=>893, 65247=>375, 65248=>408, 65249=>733, 65250=>784, 65251=>619, 65252=>670, 65253=>854, 65254=>900, 65255=>375, + 65256=>408, 65257=>590, 65258=>606, 65259=>693, 65260=>660, 65261=>622, 65262=>627, 65263=>917, 65264=>1012, 65265=>917, 65266=>1012, 65267=>375, 65268=>408, 65269=>745, 65270=>759, 65271=>745, + 65272=>759, 65273=>745, 65274=>759, 65275=>745, 65276=>759, 65279=>0, 65533=>1113}; + font[:enc]=''; + font[:diff]=''; + font[:file]='DejaVuSans-Bold.z'; + font[:ctg]='DejaVuSans-Bold.ctg.z'; + font[:originalsize]=494260; +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/dejavusansi.rb b/lib/plugins/rfpdf/lib/fonts/dejavusansi.rb new file mode 100644 index 000000000..ffb6fd636 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/dejavusansi.rb @@ -0,0 +1,267 @@ +TCPDFFontDescriptor.define('dejavusansi') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='DejaVuSans-Oblique'; + font[:desc]={'Ascent'=>928,'Descent'=>-236,'CapHeight'=>928,'Flags'=>96,'FontBBox'=>'[-1016 -385 1659 1068]','ItalicAngle'=>-11,'StemV'=>70,'MissingWidth'=>600}; + font[:up]=-42; + font[:ut]=44; + font[:cw]={ + 0=>600, 32=>318, 33=>401, 34=>460, 35=>838, 36=>636, 37=>950, 38=>780, 39=>275, 40=>390, 41=>390, 42=>500, 43=>838, 44=>318, 45=>361, 46=>318, + 47=>337, 48=>636, 49=>636, 50=>636, 51=>636, 52=>636, 53=>636, 54=>636, 55=>636, 56=>636, 57=>636, 58=>337, 59=>337, 60=>838, 61=>838, 62=>838, + 63=>531, 64=>1000, 65=>684, 66=>686, 67=>698, 68=>770, 69=>632, 70=>575, 71=>775, 72=>752, 73=>295, 74=>295, 75=>656, 76=>557, 77=>863, 78=>748, + 79=>787, 80=>603, 81=>787, 82=>695, 83=>635, 84=>611, 85=>732, 86=>684, 87=>989, 88=>685, 89=>611, 90=>685, 91=>390, 92=>337, 93=>390, 94=>838, + 95=>500, 96=>500, 97=>613, 98=>635, 99=>550, 100=>635, 101=>615, 102=>352, 103=>635, 104=>634, 105=>278, 106=>278, 107=>579, 108=>278, 109=>974, 110=>634, + 111=>612, 112=>635, 113=>635, 114=>411, 115=>521, 116=>392, 117=>634, 118=>592, 119=>818, 120=>592, 121=>592, 122=>525, 123=>636, 124=>337, 125=>636, 126=>838, + 8364=>636, 1027=>557, 8218=>318, 402=>352, 8222=>518, 8230=>1000, 8224=>500, 8225=>500, 710=>500, 8240=>1350, 352=>635, 8249=>400, 338=>1070, 1036=>710, 381=>685, 1039=>752, + 8216=>318, 8217=>318, 8220=>518, 8221=>518, 8226=>590, 8211=>500, 8212=>1000, 732=>500, 8482=>1000, 353=>521, 8250=>400, 339=>1028, 1116=>604, 382=>525, 376=>611, 160=>318, + 161=>401, 162=>636, 163=>636, 164=>636, 165=>636, 166=>337, 167=>500, 168=>500, 169=>1000, 170=>471, 171=>617, 172=>838, 173=>361, 174=>1000, 175=>500, 176=>500, + 177=>838, 178=>401, 179=>401, 180=>500, 181=>636, 182=>636, 183=>318, 184=>500, 185=>401, 186=>471, 187=>617, 188=>969, 189=>969, 190=>969, 191=>531, 192=>684, + 193=>684, 194=>684, 195=>684, 196=>684, 197=>684, 198=>974, 199=>698, 200=>632, 201=>632, 202=>632, 203=>632, 204=>295, 205=>295, 206=>295, 207=>295, 208=>775, + 209=>748, 210=>787, 211=>787, 212=>787, 213=>787, 214=>787, 215=>838, 216=>787, 217=>732, 218=>732, 219=>732, 220=>732, 221=>611, 222=>608, 223=>630, 224=>613, + 225=>613, 226=>613, 227=>613, 228=>613, 229=>613, 230=>995, 231=>550, 232=>615, 233=>615, 234=>615, 235=>615, 236=>278, 237=>278, 238=>278, 239=>278, 240=>612, + 241=>634, 242=>612, 243=>612, 244=>612, 245=>612, 246=>612, 247=>838, 248=>612, 249=>634, 250=>634, 251=>634, 252=>634, 253=>592, 254=>635, 255=>592, 256=>684, + 257=>613, 258=>684, 259=>613, 260=>684, 261=>613, 262=>698, 263=>550, 264=>698, 265=>550, 266=>698, 267=>550, 268=>698, 269=>550, 270=>770, 271=>635, 272=>775, + 273=>635, 274=>632, 275=>615, 276=>632, 277=>615, 278=>632, 279=>615, 280=>632, 281=>615, 282=>632, 283=>615, 284=>775, 285=>635, 286=>775, 287=>635, 288=>775, + 289=>635, 290=>775, 291=>635, 292=>752, 293=>634, 294=>916, 295=>695, 296=>295, 297=>278, 298=>295, 299=>278, 300=>295, 301=>278, 302=>295, 303=>278, 304=>295, + 305=>278, 306=>590, 307=>556, 308=>295, 309=>278, 310=>656, 311=>579, 312=>579, 313=>557, 314=>278, 315=>557, 316=>278, 317=>557, 318=>329, 319=>557, 320=>596, + 321=>562, 322=>287, 323=>748, 324=>634, 325=>748, 326=>634, 327=>748, 328=>634, 329=>813, 330=>748, 331=>634, 332=>787, 333=>612, 334=>787, 335=>612, 336=>787, + 337=>612, 340=>695, 341=>411, 342=>695, 343=>411, 344=>695, 345=>411, 346=>635, 347=>521, 348=>635, 349=>521, 350=>635, 351=>521, 354=>611, 355=>392, 356=>611, + 357=>392, 358=>611, 359=>392, 360=>732, 361=>634, 362=>732, 363=>634, 364=>732, 365=>634, 366=>732, 367=>634, 368=>732, 369=>634, 370=>732, 371=>634, 372=>989, + 373=>818, 374=>611, 375=>592, 377=>685, 378=>525, 379=>685, 380=>525, 383=>352, 384=>635, 385=>735, 386=>686, 387=>635, 388=>686, 389=>635, 390=>703, 391=>698, + 392=>550, 393=>775, 394=>819, 395=>686, 396=>635, 397=>612, 398=>632, 399=>787, 400=>614, 401=>575, 403=>775, 404=>687, 405=>984, 406=>354, 407=>295, 408=>746, + 409=>579, 410=>278, 411=>592, 412=>974, 413=>748, 414=>634, 415=>787, 416=>913, 417=>612, 418=>938, 419=>737, 420=>652, 421=>635, 422=>695, 423=>635, 424=>521, + 425=>632, 426=>336, 427=>392, 428=>611, 429=>392, 430=>611, 431=>838, 432=>634, 433=>764, 434=>721, 435=>744, 436=>729, 437=>685, 438=>525, 439=>666, 440=>666, + 441=>578, 442=>525, 443=>636, 444=>666, 445=>578, 446=>510, 447=>635, 448=>295, 449=>492, 450=>459, 451=>295, 452=>1455, 453=>1295, 454=>1160, 455=>852, 456=>835, + 457=>556, 458=>1043, 459=>1026, 460=>912, 461=>684, 462=>613, 463=>295, 464=>278, 465=>787, 466=>612, 467=>732, 468=>634, 469=>732, 470=>634, 471=>732, 472=>634, + 473=>732, 474=>634, 475=>732, 476=>634, 477=>615, 478=>684, 479=>613, 480=>684, 481=>613, 482=>974, 483=>995, 484=>775, 485=>635, 486=>775, 487=>635, 488=>656, + 489=>579, 490=>787, 491=>612, 492=>787, 493=>612, 494=>666, 495=>525, 496=>278, 497=>1455, 498=>1295, 499=>1160, 500=>775, 501=>635, 502=>1113, 503=>682, 504=>748, + 505=>634, 506=>684, 507=>613, 508=>974, 509=>995, 510=>787, 511=>612, 512=>684, 513=>613, 514=>684, 515=>613, 516=>632, 517=>615, 518=>632, 519=>615, 520=>295, + 521=>278, 522=>295, 523=>278, 524=>787, 525=>612, 526=>787, 527=>612, 528=>695, 529=>411, 530=>695, 531=>411, 532=>732, 533=>634, 534=>732, 535=>634, 536=>635, + 537=>521, 538=>611, 539=>392, 540=>627, 541=>521, 542=>752, 543=>634, 544=>735, 545=>838, 546=>698, 547=>610, 548=>685, 549=>525, 550=>684, 551=>613, 552=>632, + 553=>615, 554=>787, 555=>612, 556=>787, 557=>612, 558=>787, 559=>612, 560=>787, 561=>612, 562=>611, 563=>592, 564=>475, 565=>843, 566=>477, 567=>278, 568=>998, + 569=>998, 570=>684, 571=>698, 572=>550, 573=>557, 574=>611, 575=>521, 576=>525, 577=>603, 578=>479, 579=>686, 580=>732, 581=>684, 582=>632, 583=>615, 584=>295, + 585=>278, 586=>781, 587=>635, 588=>695, 589=>411, 590=>611, 591=>592, 592=>613, 593=>635, 594=>635, 595=>635, 596=>550, 597=>550, 598=>635, 599=>727, 600=>615, + 601=>615, 602=>844, 603=>545, 604=>545, 605=>775, 606=>664, 607=>326, 608=>696, 609=>635, 610=>629, 611=>596, 612=>596, 613=>634, 614=>634, 615=>634, 616=>372, + 617=>387, 618=>372, 619=>396, 620=>487, 621=>278, 622=>706, 623=>974, 624=>974, 625=>974, 626=>646, 627=>642, 628=>634, 629=>612, 630=>858, 631=>728, 632=>660, + 633=>469, 634=>469, 635=>469, 636=>469, 637=>469, 638=>530, 639=>530, 640=>602, 641=>602, 642=>521, 643=>336, 644=>336, 645=>461, 646=>336, 647=>392, 648=>392, + 649=>634, 650=>618, 651=>598, 652=>592, 653=>818, 654=>592, 655=>611, 656=>525, 657=>525, 658=>578, 659=>578, 660=>510, 661=>510, 662=>510, 663=>510, 664=>787, + 665=>580, 666=>664, 667=>708, 668=>654, 669=>292, 670=>667, 671=>507, 672=>727, 673=>510, 674=>510, 675=>1014, 676=>1058, 677=>1013, 678=>824, 679=>610, 680=>778, + 681=>848, 682=>641, 683=>654, 684=>515, 685=>515, 686=>570, 687=>664, 688=>399, 689=>399, 690=>175, 691=>259, 692=>295, 693=>296, 694=>379, 695=>515, 696=>373, + 697=>278, 698=>460, 699=>318, 700=>318, 701=>318, 702=>307, 703=>307, 704=>370, 705=>370, 706=>500, 707=>500, 708=>500, 709=>500, 711=>500, 712=>275, 713=>500, + 714=>500, 715=>500, 716=>275, 717=>500, 718=>500, 719=>500, 720=>337, 721=>337, 722=>307, 723=>307, 724=>500, 725=>500, 726=>413, 727=>500, 728=>500, 729=>500, + 730=>500, 731=>500, 733=>500, 734=>315, 735=>500, 736=>426, 737=>166, 738=>373, 739=>444, 740=>370, 741=>493, 742=>493, 743=>493, 744=>493, 745=>493, 748=>500, + 749=>500, 750=>500, 755=>500, 759=>500, 768=>0, 769=>0, 770=>0, 771=>0, 772=>0, 773=>0, 774=>0, 775=>0, 776=>0, 777=>0, 778=>0, 779=>0, + 780=>0, 781=>0, 782=>0, 783=>0, 784=>0, 785=>0, 786=>0, 787=>0, 788=>0, 789=>0, 790=>0, 791=>0, 792=>0, 793=>0, 794=>0, 795=>0, + 796=>0, 797=>0, 798=>0, 799=>0, 800=>0, 801=>0, 802=>0, 803=>0, 804=>0, 805=>0, 806=>0, 807=>0, 808=>0, 809=>0, 810=>0, 811=>0, + 812=>0, 813=>0, 814=>0, 815=>0, 816=>0, 817=>0, 818=>0, 819=>0, 820=>0, 821=>0, 822=>0, 823=>0, 824=>0, 825=>0, 826=>0, 827=>0, + 828=>0, 829=>0, 830=>0, 831=>0, 832=>0, 833=>0, 834=>0, 835=>0, 836=>0, 837=>0, 838=>0, 839=>0, 840=>0, 841=>0, 842=>0, 843=>0, + 844=>0, 845=>0, 846=>0, 847=>0, 849=>0, 855=>0, 856=>0, 860=>0, 861=>0, 862=>0, 863=>0, 864=>0, 865=>0, 866=>0, 884=>278, 885=>278, + 890=>500, 891=>549, 892=>550, 893=>549, 894=>337, 900=>500, 901=>500, 902=>695, 903=>318, 904=>767, 905=>903, 906=>435, 908=>839, 910=>860, 911=>905, 912=>338, + 913=>684, 914=>686, 915=>557, 916=>684, 917=>632, 918=>685, 919=>752, 920=>787, 921=>295, 922=>656, 923=>684, 924=>863, 925=>748, 926=>632, 927=>787, 928=>752, + 929=>603, 931=>632, 932=>611, 933=>611, 934=>787, 935=>685, 936=>787, 937=>764, 938=>295, 939=>611, 940=>659, 941=>543, 942=>631, 943=>338, 944=>579, 945=>659, + 946=>638, 947=>592, 948=>612, 949=>541, 950=>544, 951=>634, 952=>612, 953=>338, 954=>589, 955=>592, 956=>636, 957=>559, 958=>558, 959=>612, 960=>602, 961=>635, + 962=>587, 963=>634, 964=>602, 965=>579, 966=>660, 967=>592, 968=>660, 969=>837, 970=>338, 971=>579, 972=>612, 973=>579, 974=>837, 976=>614, 977=>619, 978=>699, + 979=>842, 980=>699, 981=>660, 982=>837, 983=>664, 984=>787, 985=>612, 986=>648, 987=>587, 988=>575, 989=>458, 990=>660, 991=>660, 992=>865, 993=>627, 994=>934, + 995=>837, 996=>758, 997=>659, 998=>792, 999=>615, 1000=>687, 1001=>607, 1002=>768, 1003=>625, 1004=>699, 1005=>612, 1006=>611, 1007=>536, 1008=>664, 1009=>635, 1010=>550, + 1011=>278, 1012=>787, 1013=>615, 1014=>615, 1015=>608, 1016=>635, 1017=>698, 1018=>863, 1019=>651, 1020=>635, 1021=>703, 1022=>698, 1023=>703, 1024=>632, 1025=>632, 1026=>786, + 1028=>698, 1029=>635, 1030=>295, 1031=>295, 1032=>295, 1033=>1094, 1034=>1045, 1035=>786, 1037=>748, 1038=>609, 1040=>684, 1041=>686, 1042=>686, 1043=>557, 1044=>781, 1045=>632, + 1046=>1077, 1047=>641, 1048=>748, 1049=>748, 1050=>710, 1051=>752, 1052=>863, 1053=>752, 1054=>787, 1055=>752, 1056=>603, 1057=>698, 1058=>611, 1059=>609, 1060=>861, 1061=>685, + 1062=>776, 1063=>686, 1064=>1069, 1065=>1094, 1066=>833, 1067=>818, 1068=>686, 1069=>698, 1070=>1080, 1071=>695, 1072=>613, 1073=>617, 1074=>589, 1075=>525, 1076=>691, 1077=>615, + 1078=>901, 1079=>532, 1080=>650, 1081=>650, 1082=>604, 1083=>639, 1084=>754, 1085=>654, 1086=>612, 1087=>654, 1088=>635, 1089=>550, 1090=>583, 1091=>592, 1092=>855, 1093=>592, + 1094=>681, 1095=>591, 1096=>915, 1097=>942, 1098=>707, 1099=>790, 1100=>589, 1101=>549, 1102=>842, 1103=>602, 1104=>615, 1105=>615, 1106=>625, 1107=>525, 1108=>549, 1109=>521, + 1110=>278, 1111=>278, 1112=>278, 1113=>902, 1114=>898, 1115=>652, 1117=>650, 1118=>592, 1119=>654, 1120=>934, 1121=>837, 1122=>771, 1123=>672, 1124=>942, 1125=>749, 1126=>879, + 1127=>783, 1128=>1160, 1129=>1001, 1130=>787, 1131=>612, 1132=>1027, 1133=>824, 1134=>636, 1135=>541, 1136=>856, 1137=>876, 1138=>787, 1139=>592, 1140=>781, 1141=>665, 1142=>781, + 1143=>665, 1144=>992, 1145=>904, 1146=>953, 1147=>758, 1148=>1180, 1149=>1028, 1150=>934, 1151=>837, 1152=>698, 1153=>550, 1154=>502, 1155=>0, 1156=>0, 1157=>0, 1158=>0, + 1160=>418, 1161=>418, 1162=>748, 1163=>657, 1164=>686, 1165=>589, 1166=>603, 1167=>635, 1168=>610, 1169=>525, 1170=>675, 1171=>556, 1172=>557, 1173=>491, 1174=>1077, 1175=>901, + 1176=>641, 1177=>532, 1178=>710, 1179=>604, 1180=>710, 1181=>604, 1182=>710, 1183=>604, 1184=>856, 1185=>832, 1186=>752, 1187=>661, 1188=>1014, 1189=>877, 1190=>1113, 1191=>950, + 1192=>796, 1193=>651, 1194=>698, 1195=>550, 1196=>611, 1197=>529, 1198=>611, 1199=>592, 1200=>611, 1201=>592, 1202=>685, 1203=>592, 1204=>934, 1205=>807, 1206=>686, 1207=>591, + 1208=>686, 1209=>591, 1210=>686, 1211=>634, 1212=>929, 1213=>731, 1214=>929, 1215=>731, 1216=>295, 1217=>1077, 1218=>901, 1219=>655, 1220=>604, 1221=>752, 1222=>639, 1223=>752, + 1224=>661, 1225=>752, 1226=>661, 1227=>686, 1228=>591, 1229=>863, 1230=>754, 1231=>278, 1232=>684, 1233=>613, 1234=>684, 1235=>613, 1236=>974, 1237=>995, 1238=>632, 1239=>615, + 1240=>787, 1241=>615, 1242=>787, 1243=>615, 1244=>1077, 1245=>901, 1246=>641, 1247=>532, 1248=>666, 1249=>578, 1250=>748, 1251=>650, 1252=>748, 1253=>650, 1254=>787, 1255=>612, + 1256=>787, 1257=>612, 1258=>787, 1259=>612, 1260=>698, 1261=>549, 1262=>609, 1263=>592, 1264=>609, 1265=>592, 1266=>609, 1267=>592, 1268=>686, 1269=>591, 1270=>557, 1271=>491, + 1272=>818, 1273=>790, 1274=>675, 1275=>556, 1276=>685, 1277=>592, 1278=>685, 1279=>592, 1280=>686, 1281=>589, 1282=>1006, 1283=>897, 1284=>975, 1285=>869, 1286=>679, 1287=>588, + 1288=>1072, 1289=>957, 1290=>1072, 1291=>967, 1292=>775, 1293=>660, 1294=>773, 1295=>711, 1296=>614, 1297=>541, 1298=>752, 1299=>639, 1329=>867, 1330=>732, 1331=>882, 1332=>882, + 1333=>732, 1334=>644, 1335=>682, 1336=>732, 1337=>851, 1338=>882, 1339=>732, 1340=>557, 1341=>824, 1342=>986, 1343=>732, 1344=>707, 1345=>644, 1346=>882, 1347=>777, 1348=>882, + 1349=>732, 1350=>840, 1351=>732, 1352=>732, 1353=>732, 1354=>791, 1355=>644, 1356=>882, 1357=>732, 1358=>882, 1359=>635, 1360=>732, 1361=>732, 1362=>799, 1363=>861, 1364=>790, + 1365=>787, 1366=>635, 1369=>307, 1370=>318, 1371=>500, 1372=>500, 1373=>392, 1374=>526, 1375=>500, 1377=>974, 1378=>634, 1379=>762, 1380=>767, 1381=>634, 1382=>697, 1383=>533, + 1384=>634, 1385=>700, 1386=>697, 1387=>634, 1388=>404, 1389=>894, 1390=>641, 1391=>634, 1392=>634, 1393=>635, 1394=>702, 1395=>634, 1396=>659, 1397=>278, 1398=>760, 1399=>516, + 1400=>634, 1401=>453, 1402=>974, 1403=>516, 1404=>769, 1405=>634, 1406=>696, 1407=>974, 1408=>634, 1409=>690, 1410=>501, 1411=>974, 1412=>648, 1413=>612, 1414=>629, 1415=>763, + 1417=>337, 1418=>433, 1456=>0, 1457=>0, 1458=>0, 1459=>0, 1460=>0, 1461=>0, 1462=>0, 1463=>0, 1464=>0, 1465=>0, 1467=>0, 1468=>0, 1469=>0, 1471=>0, + 1472=>295, 1473=>0, 1474=>0, 1475=>295, 1478=>456, 1479=>0, 1488=>629, 1489=>608, 1490=>448, 1491=>594, 1492=>640, 1493=>272, 1494=>423, 1495=>640, 1496=>648, 1497=>272, + 1498=>592, 1499=>556, 1500=>599, 1501=>640, 1502=>659, 1503=>272, 1504=>441, 1505=>700, 1506=>636, 1507=>640, 1508=>604, 1509=>521, 1510=>581, 1511=>663, 1512=>592, 1513=>808, + 1514=>657, 1520=>471, 1521=>454, 1522=>471, 3647=>652, 3713=>670, 3714=>684, 3716=>688, 3719=>482, 3720=>628, 3722=>684, 3725=>688, 3732=>642, 3733=>642, 3734=>672, 3735=>655, + 3737=>641, 3738=>592, 3739=>592, 3740=>745, 3741=>767, 3742=>687, 3743=>687, 3745=>702, 3746=>688, 3747=>684, 3749=>649, 3751=>632, 3754=>703, 3755=>819, 3757=>633, 3758=>684, + 3759=>788, 3760=>632, 3761=>0, 3762=>539, 3763=>539, 3764=>0, 3765=>0, 3766=>0, 3767=>0, 3768=>0, 3769=>0, 3771=>0, 3772=>0, 3773=>663, 3776=>360, 3777=>679, + 3778=>460, 3779=>547, 3780=>491, 3782=>674, 3784=>0, 3785=>0, 3786=>0, 3787=>0, 3788=>0, 3789=>0, 3804=>1028, 3805=>1028, 5121=>684, 5122=>684, 5123=>684, 5124=>684, + 5125=>769, 5126=>809, 5127=>809, 5129=>809, 5130=>769, 5131=>719, 5132=>835, 5133=>834, 5134=>835, 5135=>834, 5136=>835, 5137=>834, 5138=>967, 5139=>1007, 5140=>967, 5141=>1007, + 5142=>809, 5143=>967, 5144=>1007, 5145=>967, 5146=>1007, 5147=>719, 5149=>256, 5150=>543, 5151=>423, 5152=>423, 5153=>389, 5154=>389, 5155=>393, 5156=>389, 5157=>466, 5158=>385, + 5159=>256, 5160=>389, 5161=>389, 5162=>389, 5163=>1090, 5164=>909, 5165=>953, 5166=>1117, 5167=>684, 5168=>684, 5169=>684, 5170=>684, 5171=>729, 5172=>629, 5173=>629, 5175=>629, + 5176=>729, 5177=>629, 5178=>835, 5179=>684, 5180=>835, 5181=>834, 5182=>835, 5183=>834, 5184=>967, 5185=>1007, 5186=>967, 5187=>1007, 5188=>967, 5189=>1007, 5190=>967, 5191=>1007, + 5192=>729, 5193=>508, 5194=>192, 5196=>732, 5197=>732, 5198=>732, 5199=>732, 5200=>730, 5201=>730, 5202=>730, 5204=>730, 5205=>730, 5206=>730, 5207=>921, 5208=>889, 5209=>921, + 5210=>889, 5211=>921, 5212=>889, 5213=>928, 5214=>900, 5215=>928, 5216=>900, 5217=>947, 5218=>900, 5219=>947, 5220=>900, 5221=>947, 5222=>434, 5223=>877, 5224=>877, 5225=>866, + 5226=>890, 5227=>628, 5228=>628, 5229=>628, 5230=>628, 5231=>628, 5232=>628, 5233=>628, 5234=>628, 5235=>628, 5236=>860, 5237=>771, 5238=>815, 5239=>816, 5240=>815, 5241=>816, + 5242=>860, 5243=>771, 5244=>860, 5245=>771, 5246=>815, 5247=>816, 5248=>815, 5249=>816, 5250=>815, 5251=>407, 5252=>407, 5253=>750, 5254=>775, 5255=>750, 5256=>775, 5257=>628, + 5258=>628, 5259=>628, 5260=>628, 5261=>628, 5262=>628, 5263=>628, 5264=>628, 5265=>628, 5266=>860, 5267=>771, 5268=>815, 5269=>816, 5270=>815, 5271=>816, 5272=>860, 5273=>771, + 5274=>860, 5275=>771, 5276=>815, 5277=>816, 5278=>815, 5279=>816, 5280=>815, 5281=>435, 5282=>435, 5283=>610, 5284=>522, 5285=>557, 5286=>522, 5287=>610, 5288=>610, 5289=>522, + 5290=>557, 5291=>557, 5292=>749, 5293=>769, 5294=>746, 5295=>764, 5296=>746, 5297=>764, 5298=>749, 5299=>769, 5300=>749, 5301=>769, 5302=>746, 5303=>764, 5304=>746, 5305=>764, + 5306=>746, 5307=>386, 5308=>508, 5309=>386, 5312=>852, 5313=>852, 5314=>852, 5315=>852, 5316=>852, 5317=>799, 5318=>799, 5319=>852, 5320=>799, 5321=>1069, 5322=>1035, 5323=>1059, + 5324=>852, 5325=>1059, 5326=>799, 5327=>852, 5328=>600, 5329=>453, 5330=>600, 5331=>852, 5332=>852, 5333=>852, 5334=>852, 5335=>852, 5336=>799, 5337=>799, 5338=>852, 5339=>799, + 5340=>1069, 5341=>1035, 5342=>1059, 5343=>1030, 5344=>1059, 5345=>1030, 5346=>1069, 5347=>1035, 5348=>1069, 5349=>1035, 5350=>1083, 5351=>1030, 5352=>1083, 5353=>1030, 5354=>600, 5356=>729, + 5357=>603, 5358=>603, 5359=>603, 5360=>603, 5361=>603, 5362=>603, 5363=>603, 5364=>603, 5365=>603, 5366=>834, 5367=>754, 5368=>792, 5369=>771, 5370=>792, 5371=>771, 5372=>834, + 5373=>754, 5374=>834, 5375=>754, 5376=>792, 5377=>771, 5378=>792, 5379=>771, 5380=>792, 5381=>418, 5382=>420, 5383=>418, 5392=>712, 5393=>712, 5394=>712, 5395=>892, 5396=>892, + 5397=>892, 5398=>892, 5399=>910, 5400=>872, 5401=>910, 5402=>872, 5403=>910, 5404=>872, 5405=>1140, 5406=>1100, 5407=>1140, 5408=>1100, 5409=>1140, 5410=>1100, 5411=>1140, 5412=>1100, + 5413=>641, 5414=>627, 5415=>627, 5416=>627, 5417=>627, 5418=>627, 5419=>627, 5420=>627, 5421=>627, 5422=>627, 5423=>844, 5424=>781, 5425=>816, 5426=>818, 5427=>816, 5428=>818, + 5429=>844, 5430=>781, 5431=>844, 5432=>781, 5433=>816, 5434=>818, 5435=>816, 5436=>818, 5437=>816, 5438=>418, 5440=>389, 5441=>484, 5442=>916, 5443=>916, 5444=>863, 5445=>916, + 5446=>863, 5447=>863, 5448=>603, 5449=>603, 5450=>603, 5451=>603, 5452=>603, 5453=>603, 5454=>834, 5455=>754, 5456=>418, 5458=>729, 5459=>684, 5460=>684, 5461=>684, 5462=>684, + 5463=>726, 5464=>672, 5465=>726, 5466=>726, 5467=>924, 5468=>1007, 5469=>508, 5470=>732, 5471=>732, 5472=>732, 5473=>732, 5474=>732, 5475=>732, 5476=>730, 5477=>730, 5478=>730, + 5479=>730, 5480=>947, 5481=>900, 5482=>508, 5492=>831, 5493=>831, 5494=>831, 5495=>831, 5496=>831, 5497=>831, 5498=>831, 5499=>563, 5500=>752, 5501=>484, 5502=>1047, 5503=>1047, + 5504=>1047, 5505=>1047, 5506=>1047, 5507=>1047, 5508=>1047, 5509=>825, 5514=>831, 5515=>831, 5516=>831, 5517=>831, 5518=>1259, 5519=>1259, 5520=>1259, 5521=>1002, 5522=>1002, 5523=>1259, + 5524=>1259, 5525=>700, 5526=>1073, 5536=>852, 5537=>852, 5538=>799, 5539=>799, 5540=>799, 5541=>799, 5542=>600, 5543=>643, 5544=>643, 5545=>643, 5546=>643, 5547=>643, 5548=>643, + 5549=>643, 5550=>418, 5551=>628, 5598=>770, 5601=>770, 5702=>468, 5703=>468, 5742=>444, 5743=>1047, 5744=>1310, 5745=>1632, 5746=>1632, 5747=>1375, 5748=>1375, 5749=>1632, 5750=>1632, + 7424=>592, 7425=>717, 7426=>982, 7427=>586, 7428=>550, 7429=>605, 7430=>605, 7431=>491, 7432=>541, 7433=>278, 7434=>395, 7435=>579, 7436=>583, 7437=>754, 7438=>650, 7439=>612, + 7440=>550, 7441=>684, 7442=>684, 7443=>684, 7444=>1023, 7446=>612, 7447=>612, 7448=>524, 7449=>602, 7450=>602, 7451=>583, 7452=>574, 7453=>737, 7454=>948, 7455=>638, 7456=>592, + 7457=>818, 7458=>525, 7459=>526, 7462=>583, 7463=>592, 7464=>564, 7465=>524, 7466=>590, 7467=>639, 7468=>431, 7469=>613, 7470=>432, 7472=>485, 7473=>398, 7474=>398, 7475=>488, + 7476=>474, 7477=>186, 7478=>186, 7479=>413, 7480=>351, 7481=>543, 7482=>471, 7483=>471, 7484=>496, 7485=>439, 7486=>380, 7487=>438, 7488=>385, 7489=>461, 7490=>623, 7491=>392, + 7492=>392, 7493=>405, 7494=>648, 7495=>428, 7496=>405, 7497=>417, 7498=>417, 7499=>360, 7500=>359, 7501=>405, 7502=>179, 7503=>426, 7504=>623, 7505=>409, 7506=>414, 7507=>370, + 7508=>414, 7509=>414, 7510=>428, 7511=>295, 7512=>405, 7513=>470, 7514=>623, 7515=>417, 7516=>1000, 7517=>402, 7518=>373, 7519=>385, 7520=>416, 7521=>364, 7522=>179, 7523=>259, + 7524=>405, 7525=>417, 7526=>402, 7527=>373, 7528=>385, 7529=>416, 7530=>364, 7543=>635, 7544=>474, 7547=>372, 7557=>278, 7579=>405, 7580=>370, 7581=>370, 7582=>414, 7583=>360, + 7584=>296, 7585=>233, 7586=>405, 7587=>405, 7588=>261, 7589=>250, 7590=>261, 7591=>261, 7592=>234, 7593=>250, 7594=>235, 7595=>376, 7596=>623, 7597=>623, 7598=>411, 7599=>479, + 7600=>409, 7601=>414, 7602=>414, 7603=>360, 7604=>287, 7605=>295, 7606=>508, 7607=>418, 7608=>361, 7609=>406, 7610=>417, 7611=>366, 7612=>437, 7613=>366, 7614=>392, 7615=>414, + 7620=>0, 7621=>0, 7622=>0, 7623=>0, 7624=>0, 7625=>0, 7680=>684, 7681=>613, 7682=>686, 7683=>635, 7684=>686, 7685=>635, 7686=>686, 7687=>635, 7688=>698, 7689=>550, + 7690=>770, 7691=>635, 7692=>770, 7693=>635, 7694=>770, 7695=>635, 7696=>770, 7697=>635, 7698=>770, 7699=>635, 7700=>632, 7701=>615, 7702=>632, 7703=>615, 7704=>632, 7705=>615, + 7706=>632, 7707=>615, 7708=>632, 7709=>615, 7710=>575, 7711=>352, 7712=>775, 7713=>635, 7714=>752, 7715=>634, 7716=>752, 7717=>634, 7718=>752, 7719=>634, 7720=>752, 7721=>634, + 7722=>752, 7723=>634, 7724=>295, 7725=>278, 7726=>295, 7727=>278, 7728=>656, 7729=>579, 7730=>656, 7731=>579, 7732=>656, 7733=>579, 7734=>557, 7735=>278, 7736=>557, 7737=>278, + 7738=>557, 7739=>278, 7740=>557, 7741=>278, 7742=>863, 7743=>974, 7744=>863, 7745=>974, 7746=>863, 7747=>974, 7748=>748, 7749=>634, 7750=>748, 7751=>634, 7752=>748, 7753=>634, + 7754=>748, 7755=>634, 7756=>787, 7757=>612, 7758=>787, 7759=>612, 7760=>787, 7761=>612, 7762=>787, 7763=>612, 7764=>603, 7765=>635, 7766=>603, 7767=>635, 7768=>695, 7769=>411, + 7770=>695, 7771=>411, 7772=>695, 7773=>411, 7774=>695, 7775=>411, 7776=>635, 7777=>521, 7778=>635, 7779=>521, 7780=>635, 7781=>521, 7782=>635, 7783=>521, 7784=>635, 7785=>521, + 7786=>611, 7787=>392, 7788=>611, 7789=>392, 7790=>611, 7791=>392, 7792=>611, 7793=>392, 7794=>732, 7795=>634, 7796=>732, 7797=>634, 7798=>732, 7799=>634, 7800=>732, 7801=>634, + 7802=>732, 7803=>634, 7804=>684, 7805=>592, 7806=>684, 7807=>592, 7808=>989, 7809=>818, 7810=>989, 7811=>818, 7812=>989, 7813=>818, 7814=>989, 7815=>818, 7816=>989, 7817=>818, + 7818=>685, 7819=>592, 7820=>685, 7821=>592, 7822=>611, 7823=>592, 7824=>685, 7825=>525, 7826=>685, 7827=>525, 7828=>685, 7829=>525, 7830=>634, 7831=>392, 7832=>818, 7833=>592, + 7834=>613, 7835=>352, 7840=>684, 7841=>613, 7842=>684, 7843=>613, 7844=>684, 7845=>613, 7846=>684, 7847=>613, 7848=>684, 7849=>613, 7850=>684, 7851=>613, 7852=>684, 7853=>613, + 7854=>684, 7855=>613, 7856=>684, 7857=>613, 7858=>684, 7859=>613, 7860=>684, 7861=>613, 7862=>684, 7863=>613, 7864=>632, 7865=>615, 7866=>632, 7867=>615, 7868=>632, 7869=>615, + 7870=>632, 7871=>615, 7872=>632, 7873=>615, 7874=>632, 7875=>615, 7876=>632, 7877=>615, 7878=>632, 7879=>615, 7880=>295, 7881=>278, 7882=>295, 7883=>278, 7884=>787, 7885=>612, + 7886=>787, 7887=>612, 7888=>787, 7889=>612, 7890=>787, 7891=>612, 7892=>787, 7893=>612, 7894=>787, 7895=>612, 7896=>787, 7897=>612, 7898=>913, 7899=>612, 7900=>913, 7901=>612, + 7902=>913, 7903=>612, 7904=>913, 7905=>612, 7906=>913, 7907=>612, 7908=>732, 7909=>634, 7910=>732, 7911=>634, 7912=>838, 7913=>634, 7914=>838, 7915=>634, 7916=>838, 7917=>634, + 7918=>838, 7919=>634, 7920=>838, 7921=>634, 7922=>611, 7923=>592, 7924=>611, 7925=>592, 7926=>611, 7927=>592, 7928=>611, 7929=>592, 7936=>659, 7937=>659, 7938=>659, 7939=>659, + 7940=>659, 7941=>659, 7942=>659, 7943=>659, 7944=>684, 7945=>684, 7946=>877, 7947=>877, 7948=>769, 7949=>801, 7950=>708, 7951=>743, 7952=>541, 7953=>541, 7954=>541, 7955=>541, + 7956=>541, 7957=>541, 7960=>711, 7961=>711, 7962=>966, 7963=>975, 7964=>898, 7965=>928, 7968=>634, 7969=>634, 7970=>634, 7971=>634, 7972=>634, 7973=>634, 7974=>634, 7975=>634, + 7976=>837, 7977=>835, 7978=>1086, 7979=>1089, 7980=>1027, 7981=>1051, 7982=>934, 7983=>947, 7984=>338, 7985=>338, 7986=>338, 7987=>338, 7988=>338, 7989=>338, 7990=>338, 7991=>338, + 7992=>380, 7993=>374, 7994=>635, 7995=>635, 7996=>570, 7997=>600, 7998=>489, 7999=>493, 8000=>612, 8001=>612, 8002=>612, 8003=>612, 8004=>612, 8005=>612, 8008=>804, 8009=>848, + 8010=>1095, 8011=>1100, 8012=>938, 8013=>970, 8016=>579, 8017=>579, 8018=>579, 8019=>579, 8020=>579, 8021=>579, 8022=>579, 8023=>579, 8025=>784, 8027=>998, 8029=>1012, 8031=>897, + 8032=>837, 8033=>837, 8034=>837, 8035=>837, 8036=>837, 8037=>837, 8038=>837, 8039=>837, 8040=>802, 8041=>843, 8042=>1089, 8043=>1095, 8044=>946, 8045=>972, 8046=>921, 8047=>952, + 8048=>659, 8049=>659, 8050=>541, 8051=>548, 8052=>634, 8053=>654, 8054=>338, 8055=>338, 8056=>612, 8057=>612, 8058=>579, 8059=>579, 8060=>837, 8061=>837, 8064=>659, 8065=>659, + 8066=>659, 8067=>659, 8068=>659, 8069=>659, 8070=>659, 8071=>659, 8072=>684, 8073=>684, 8074=>877, 8075=>877, 8076=>769, 8077=>801, 8078=>708, 8079=>743, 8080=>634, 8081=>634, + 8082=>634, 8083=>634, 8084=>634, 8085=>634, 8086=>634, 8087=>634, 8088=>837, 8089=>835, 8090=>1086, 8091=>1089, 8092=>1027, 8093=>1051, 8094=>934, 8095=>947, 8096=>837, 8097=>837, + 8098=>837, 8099=>837, 8100=>837, 8101=>837, 8102=>837, 8103=>837, 8104=>802, 8105=>843, 8106=>1089, 8107=>1095, 8108=>946, 8109=>972, 8110=>921, 8111=>952, 8112=>659, 8113=>659, + 8114=>659, 8115=>659, 8116=>659, 8118=>659, 8119=>659, 8120=>684, 8121=>684, 8122=>716, 8123=>692, 8124=>684, 8125=>500, 8126=>500, 8127=>500, 8128=>500, 8129=>500, 8130=>634, + 8131=>634, 8132=>654, 8134=>634, 8135=>634, 8136=>805, 8137=>746, 8138=>931, 8139=>871, 8140=>752, 8141=>500, 8142=>500, 8143=>500, 8144=>338, 8145=>338, 8146=>338, 8147=>338, + 8150=>338, 8151=>338, 8152=>295, 8153=>295, 8154=>475, 8155=>408, 8157=>500, 8158=>500, 8159=>500, 8160=>579, 8161=>579, 8162=>579, 8163=>579, 8164=>635, 8165=>635, 8166=>579, + 8167=>579, 8168=>611, 8169=>611, 8170=>845, 8171=>825, 8172=>685, 8173=>500, 8174=>500, 8175=>500, 8178=>837, 8179=>837, 8180=>837, 8182=>837, 8183=>837, 8184=>941, 8185=>813, + 8186=>922, 8187=>826, 8188=>764, 8189=>500, 8190=>500, 8192=>500, 8193=>1000, 8194=>500, 8195=>1000, 8196=>330, 8197=>250, 8198=>167, 8199=>636, 8200=>318, 8201=>200, 8202=>100, + 8203=>0, 8204=>0, 8205=>0, 8206=>0, 8207=>0, 8208=>361, 8209=>361, 8210=>636, 8213=>1000, 8214=>0, 8215=>500, 8219=>318, 8223=>518, 8227=>590, 8228=>333, 8229=>667, + 8231=>318, 8234=>0, 8235=>0, 8236=>0, 8237=>0, 8238=>0, 8239=>200, 8241=>1690, 8242=>227, 8243=>374, 8244=>520, 8245=>227, 8246=>374, 8247=>520, 8248=>339, 8251=>838, + 8252=>485, 8253=>531, 8254=>500, 8255=>804, 8256=>804, 8257=>250, 8258=>1000, 8259=>500, 8260=>167, 8261=>390, 8262=>390, 8263=>922, 8264=>733, 8265=>733, 8266=>497, 8267=>636, + 8268=>500, 8269=>500, 8270=>500, 8271=>337, 8272=>804, 8273=>500, 8274=>450, 8275=>838, 8276=>804, 8277=>838, 8278=>586, 8279=>663, 8280=>838, 8281=>838, 8282=>318, 8283=>797, + 8284=>838, 8285=>318, 8286=>318, 8287=>222, 8288=>0, 8289=>0, 8290=>0, 8291=>0, 8298=>0, 8299=>0, 8300=>0, 8301=>0, 8302=>0, 8303=>0, 8304=>401, 8305=>179, + 8308=>401, 8309=>401, 8310=>401, 8311=>401, 8312=>401, 8313=>401, 8314=>528, 8315=>528, 8316=>528, 8317=>246, 8318=>246, 8319=>399, 8320=>401, 8321=>401, 8322=>401, 8323=>401, + 8324=>401, 8325=>401, 8326=>401, 8327=>401, 8328=>401, 8329=>401, 8330=>528, 8331=>528, 8332=>528, 8333=>246, 8334=>246, 8336=>392, 8337=>417, 8338=>414, 8339=>444, 8340=>417, + 8352=>877, 8353=>636, 8354=>636, 8355=>636, 8356=>636, 8357=>974, 8358=>748, 8359=>1271, 8360=>1074, 8361=>989, 8362=>838, 8363=>636, 8365=>656, 8366=>611, 8367=>1272, 8368=>636, + 8369=>636, 8370=>636, 8371=>636, 8372=>774, 8373=>641, 8400=>0, 8401=>0, 8406=>0, 8407=>0, 8448=>970, 8449=>970, 8450=>698, 8451=>1123, 8452=>896, 8453=>969, 8454=>1032, + 8455=>614, 8456=>698, 8457=>952, 8459=>988, 8460=>720, 8461=>850, 8462=>634, 8463=>634, 8464=>470, 8465=>697, 8466=>720, 8467=>413, 8468=>818, 8469=>801, 8470=>1040, 8471=>1000, + 8472=>697, 8473=>702, 8474=>787, 8475=>798, 8476=>814, 8477=>792, 8478=>896, 8479=>684, 8480=>1020, 8481=>1014, 8483=>684, 8484=>745, 8485=>578, 8486=>764, 8487=>764, 8488=>616, + 8489=>338, 8490=>656, 8491=>684, 8492=>786, 8493=>703, 8494=>854, 8495=>592, 8496=>605, 8497=>786, 8498=>575, 8499=>1069, 8500=>462, 8501=>745, 8502=>674, 8503=>450, 8504=>695, + 8505=>380, 8506=>926, 8507=>1157, 8508=>702, 8509=>728, 8510=>655, 8511=>849, 8512=>811, 8513=>775, 8514=>557, 8515=>557, 8516=>611, 8517=>819, 8518=>708, 8519=>615, 8520=>351, + 8521=>351, 8523=>780, 8526=>526, 8531=>969, 8532=>969, 8533=>969, 8534=>969, 8535=>969, 8536=>969, 8537=>969, 8538=>969, 8539=>969, 8540=>969, 8541=>969, 8542=>969, 8543=>568, + 8544=>295, 8545=>492, 8546=>689, 8547=>923, 8548=>684, 8549=>922, 8550=>1120, 8551=>1317, 8552=>917, 8553=>685, 8554=>933, 8555=>1131, 8556=>557, 8557=>698, 8558=>770, 8559=>863, + 8560=>278, 8561=>458, 8562=>637, 8563=>812, 8564=>592, 8565=>811, 8566=>991, 8567=>1170, 8568=>819, 8569=>592, 8570=>822, 8571=>1002, 8572=>278, 8573=>550, 8574=>635, 8575=>974, + 8576=>1245, 8577=>770, 8578=>1245, 8579=>703, 8580=>549, 8592=>838, 8593=>838, 8594=>838, 8595=>838, 8596=>838, 8597=>838, 8598=>838, 8599=>838, 8600=>838, 8601=>838, 8602=>838, + 8603=>838, 8604=>838, 8605=>838, 8606=>838, 8607=>838, 8608=>838, 8609=>838, 8610=>838, 8611=>838, 8612=>838, 8613=>838, 8614=>838, 8615=>838, 8616=>838, 8617=>838, 8618=>838, + 8619=>838, 8620=>838, 8621=>838, 8622=>838, 8623=>838, 8624=>838, 8625=>838, 8626=>838, 8627=>838, 8628=>838, 8629=>838, 8630=>838, 8631=>838, 8632=>838, 8633=>838, 8634=>838, + 8635=>838, 8636=>838, 8637=>838, 8638=>838, 8639=>838, 8640=>838, 8641=>838, 8642=>838, 8643=>838, 8644=>838, 8645=>838, 8646=>838, 8647=>838, 8648=>838, 8649=>838, 8650=>838, + 8651=>838, 8652=>838, 8653=>838, 8654=>838, 8655=>838, 8656=>838, 8657=>838, 8658=>838, 8659=>838, 8660=>838, 8661=>838, 8662=>838, 8663=>838, 8664=>838, 8665=>838, 8666=>838, + 8667=>838, 8668=>838, 8669=>838, 8670=>838, 8671=>838, 8672=>838, 8673=>838, 8674=>838, 8675=>838, 8676=>838, 8677=>838, 8678=>838, 8679=>838, 8680=>838, 8681=>838, 8682=>838, + 8683=>838, 8684=>838, 8685=>838, 8686=>838, 8687=>838, 8688=>838, 8689=>838, 8690=>838, 8691=>838, 8692=>838, 8693=>838, 8694=>838, 8695=>838, 8696=>838, 8697=>838, 8698=>838, + 8699=>838, 8700=>838, 8701=>838, 8702=>838, 8703=>838, 8704=>684, 8705=>636, 8706=>517, 8707=>632, 8708=>632, 8709=>871, 8710=>669, 8711=>669, 8712=>871, 8713=>871, 8714=>718, + 8715=>871, 8716=>871, 8717=>718, 8718=>636, 8719=>757, 8720=>757, 8721=>674, 8722=>838, 8723=>838, 8724=>838, 8725=>167, 8726=>637, 8727=>838, 8728=>626, 8729=>318, 8730=>637, + 8731=>637, 8732=>637, 8733=>677, 8734=>833, 8735=>838, 8736=>896, 8737=>896, 8738=>838, 8739=>500, 8740=>500, 8741=>500, 8742=>500, 8743=>732, 8744=>732, 8745=>732, 8746=>732, + 8747=>521, 8748=>789, 8749=>1057, 8750=>521, 8751=>789, 8752=>1057, 8753=>521, 8754=>521, 8755=>521, 8756=>636, 8757=>636, 8758=>260, 8759=>636, 8760=>838, 8761=>838, 8762=>838, + 8763=>838, 8764=>838, 8765=>838, 8766=>838, 8767=>838, 8768=>375, 8769=>838, 8770=>838, 8771=>838, 8772=>838, 8773=>838, 8774=>838, 8775=>838, 8776=>838, 8777=>838, 8778=>838, + 8779=>838, 8780=>838, 8781=>838, 8782=>838, 8783=>838, 8784=>838, 8785=>838, 8786=>838, 8787=>838, 8788=>1000, 8789=>1000, 8790=>838, 8791=>838, 8792=>838, 8793=>838, 8794=>838, + 8795=>838, 8796=>838, 8797=>838, 8798=>838, 8799=>838, 8800=>838, 8801=>838, 8802=>838, 8803=>838, 8804=>838, 8805=>838, 8806=>838, 8807=>838, 8808=>838, 8809=>838, 8810=>1047, + 8811=>1047, 8812=>464, 8813=>838, 8814=>838, 8815=>838, 8816=>838, 8817=>838, 8818=>838, 8819=>838, 8820=>838, 8821=>838, 8822=>838, 8823=>838, 8824=>838, 8825=>838, 8826=>838, + 8827=>838, 8828=>838, 8829=>838, 8830=>838, 8831=>838, 8832=>838, 8833=>838, 8834=>838, 8835=>838, 8836=>838, 8837=>838, 8838=>838, 8839=>838, 8840=>838, 8841=>838, 8842=>838, + 8843=>838, 8844=>732, 8845=>732, 8846=>732, 8847=>838, 8848=>838, 8849=>838, 8850=>838, 8851=>722, 8852=>722, 8853=>838, 8854=>838, 8855=>838, 8856=>838, 8857=>838, 8858=>838, + 8859=>838, 8860=>838, 8861=>838, 8862=>838, 8863=>838, 8864=>838, 8865=>838, 8866=>871, 8867=>871, 8868=>871, 8869=>871, 8870=>521, 8871=>521, 8872=>871, 8873=>871, 8874=>871, + 8875=>871, 8876=>871, 8877=>871, 8878=>871, 8879=>871, 8882=>838, 8883=>838, 8884=>838, 8885=>838, 8886=>1000, 8887=>1000, 8888=>838, 8889=>838, 8890=>521, 8891=>732, 8892=>732, + 8893=>732, 8896=>820, 8897=>820, 8898=>820, 8899=>820, 8900=>494, 8901=>318, 8902=>626, 8904=>1000, 8905=>1000, 8906=>1000, 8907=>1000, 8908=>1000, 8909=>838, 8918=>838, 8919=>838, + 8920=>1422, 8921=>1422, 8922=>838, 8923=>838, 8924=>838, 8925=>838, 8926=>838, 8927=>838, 8928=>838, 8929=>838, 8930=>838, 8931=>838, 8932=>838, 8933=>838, 8934=>838, 8935=>838, + 8936=>838, 8937=>838, 8938=>838, 8939=>838, 8940=>838, 8941=>838, 8946=>1000, 8947=>871, 8948=>718, 8949=>871, 8950=>871, 8951=>718, 8952=>871, 8953=>871, 8954=>1000, 8955=>871, + 8956=>718, 8957=>871, 8958=>718, 8959=>871, 8962=>635, 8966=>871, 8968=>390, 8969=>390, 8970=>390, 8971=>390, 8976=>838, 8977=>513, 8984=>1000, 8985=>838, 8992=>521, 8993=>521, + 8997=>1000, 9000=>1443, 9085=>757, 9115=>500, 9116=>500, 9117=>500, 9118=>500, 9119=>500, 9120=>500, 9121=>500, 9122=>500, 9123=>500, 9124=>500, 9125=>500, 9126=>500, 9127=>750, + 9128=>750, 9129=>750, 9130=>750, 9131=>750, 9132=>750, 9133=>750, 9134=>521, 9166=>838, 9167=>945, 9250=>635, 9251=>635, 9312=>896, 9313=>896, 9314=>896, 9315=>896, 9316=>896, + 9317=>896, 9318=>896, 9319=>896, 9320=>896, 9321=>896, 9600=>769, 9601=>769, 9602=>769, 9603=>769, 9604=>769, 9605=>769, 9606=>769, 9607=>769, 9608=>769, 9609=>769, 9610=>769, + 9611=>769, 9612=>769, 9613=>769, 9614=>769, 9615=>769, 9616=>769, 9617=>769, 9618=>769, 9619=>769, 9620=>769, 9621=>769, 9622=>769, 9623=>769, 9624=>769, 9625=>769, 9626=>769, + 9627=>769, 9628=>769, 9629=>769, 9630=>769, 9631=>769, 9632=>945, 9633=>945, 9634=>945, 9635=>945, 9636=>945, 9637=>945, 9638=>945, 9639=>945, 9640=>945, 9641=>945, 9642=>678, + 9643=>678, 9644=>945, 9645=>945, 9646=>550, 9647=>550, 9648=>769, 9649=>769, 9650=>769, 9651=>769, 9652=>502, 9653=>502, 9654=>769, 9655=>769, 9656=>502, 9657=>502, 9658=>769, + 9659=>769, 9660=>769, 9661=>769, 9662=>502, 9663=>502, 9664=>769, 9665=>769, 9666=>502, 9667=>502, 9668=>769, 9669=>769, 9670=>769, 9671=>769, 9672=>769, 9673=>873, 9674=>494, + 9675=>873, 9676=>873, 9677=>873, 9678=>873, 9679=>873, 9680=>873, 9681=>873, 9682=>873, 9683=>873, 9684=>873, 9685=>873, 9686=>527, 9687=>527, 9688=>791, 9689=>970, 9690=>970, + 9691=>970, 9692=>387, 9693=>387, 9694=>387, 9695=>387, 9696=>769, 9697=>769, 9698=>769, 9699=>769, 9700=>769, 9701=>769, 9702=>590, 9703=>945, 9704=>945, 9705=>945, 9706=>945, + 9707=>945, 9708=>769, 9709=>769, 9710=>769, 9711=>1119, 9712=>945, 9713=>945, 9714=>945, 9715=>945, 9716=>873, 9717=>873, 9718=>873, 9719=>873, 9720=>769, 9721=>769, 9722=>769, + 9723=>830, 9724=>830, 9725=>732, 9726=>732, 9727=>769, 9728=>896, 9729=>1000, 9730=>896, 9731=>896, 9732=>896, 9733=>896, 9734=>896, 9735=>573, 9736=>896, 9737=>896, 9738=>888, + 9739=>888, 9740=>671, 9741=>1013, 9742=>1246, 9743=>1250, 9744=>896, 9745=>896, 9746=>896, 9747=>532, 9748=>896, 9749=>896, 9750=>896, 9751=>896, 9752=>896, 9753=>896, 9754=>896, + 9755=>896, 9756=>896, 9757=>609, 9758=>896, 9759=>609, 9760=>896, 9761=>896, 9762=>896, 9763=>896, 9764=>669, 9765=>746, 9766=>649, 9767=>784, 9768=>545, 9769=>896, 9770=>896, + 9771=>896, 9772=>710, 9773=>896, 9774=>896, 9775=>896, 9776=>896, 9777=>896, 9778=>896, 9779=>896, 9780=>896, 9781=>896, 9782=>896, 9783=>896, 9784=>896, 9785=>896, 9786=>896, + 9787=>896, 9788=>896, 9789=>896, 9790=>896, 9791=>614, 9792=>731, 9793=>731, 9794=>896, 9795=>896, 9796=>896, 9797=>896, 9798=>896, 9799=>896, 9800=>896, 9801=>896, 9802=>896, + 9803=>896, 9804=>896, 9805=>896, 9806=>896, 9807=>896, 9808=>896, 9809=>896, 9810=>896, 9811=>896, 9812=>896, 9813=>896, 9814=>896, 9815=>896, 9816=>896, 9817=>896, 9818=>896, + 9819=>896, 9820=>896, 9821=>896, 9822=>896, 9823=>896, 9824=>896, 9825=>896, 9826=>896, 9827=>896, 9828=>896, 9829=>896, 9830=>896, 9831=>896, 9832=>896, 9833=>472, 9834=>638, + 9835=>896, 9836=>896, 9837=>472, 9838=>357, 9839=>484, 9840=>748, 9841=>766, 9842=>896, 9843=>896, 9844=>896, 9845=>896, 9846=>896, 9847=>896, 9848=>896, 9849=>896, 9850=>896, + 9851=>896, 9852=>896, 9853=>896, 9854=>896, 9855=>896, 9856=>869, 9857=>869, 9858=>869, 9859=>869, 9860=>869, 9861=>869, 9862=>890, 9863=>890, 9864=>890, 9865=>890, 9866=>890, + 9867=>890, 9868=>890, 9869=>890, 9870=>890, 9871=>890, 9872=>750, 9873=>750, 9874=>890, 9875=>816, 9876=>716, 9877=>537, 9878=>852, 9879=>890, 9880=>684, 9881=>890, 9882=>708, + 9883=>890, 9884=>890, 9888=>890, 9889=>890, 9890=>838, 9891=>838, 9892=>838, 9893=>838, 9894=>838, 9895=>838, 9896=>838, 9897=>838, 9898=>838, 9899=>838, 9900=>838, 9901=>838, + 9902=>838, 9903=>838, 9904=>844, 9905=>838, 9906=>731, 9985=>838, 9986=>838, 9987=>838, 9988=>838, 9990=>838, 9991=>838, 9992=>838, 9993=>838, 9996=>838, 9997=>838, 9998=>838, + 9999=>838, 10000=>838, 10001=>838, 10002=>838, 10003=>838, 10004=>838, 10005=>838, 10006=>838, 10007=>838, 10008=>838, 10009=>838, 10010=>838, 10011=>838, 10012=>838, 10013=>838, 10014=>838, + 10015=>838, 10016=>838, 10017=>838, 10018=>838, 10019=>838, 10020=>838, 10021=>838, 10022=>838, 10023=>838, 10025=>838, 10026=>838, 10027=>838, 10028=>838, 10029=>838, 10030=>838, 10031=>838, + 10032=>838, 10033=>838, 10034=>838, 10035=>838, 10036=>838, 10037=>838, 10038=>838, 10039=>838, 10040=>838, 10041=>838, 10042=>838, 10043=>838, 10044=>838, 10045=>838, 10046=>838, 10047=>838, + 10048=>838, 10049=>838, 10050=>838, 10051=>838, 10052=>838, 10053=>838, 10054=>838, 10055=>838, 10056=>838, 10057=>838, 10058=>838, 10059=>838, 10061=>896, 10063=>896, 10064=>896, 10065=>896, + 10066=>896, 10070=>896, 10072=>838, 10073=>838, 10074=>838, 10075=>322, 10076=>322, 10077=>538, 10078=>538, 10081=>838, 10082=>838, 10083=>838, 10084=>838, 10085=>838, 10086=>838, 10087=>838, + 10088=>838, 10089=>838, 10090=>838, 10091=>838, 10092=>838, 10093=>838, 10094=>838, 10095=>838, 10096=>838, 10097=>838, 10098=>838, 10099=>838, 10100=>838, 10101=>838, 10102=>896, 10103=>896, + 10104=>896, 10105=>896, 10106=>896, 10107=>896, 10108=>896, 10109=>896, 10110=>896, 10111=>896, 10112=>838, 10113=>838, 10114=>838, 10115=>838, 10116=>838, 10117=>838, 10118=>838, 10119=>838, + 10120=>838, 10121=>838, 10122=>838, 10123=>838, 10124=>838, 10125=>838, 10126=>838, 10127=>838, 10128=>838, 10129=>838, 10130=>838, 10131=>838, 10132=>838, 10136=>838, 10137=>838, 10138=>838, + 10139=>838, 10140=>838, 10141=>838, 10142=>838, 10143=>838, 10144=>838, 10145=>838, 10146=>838, 10147=>838, 10148=>838, 10149=>838, 10150=>838, 10151=>838, 10152=>838, 10153=>838, 10154=>838, + 10155=>838, 10156=>838, 10157=>838, 10158=>838, 10159=>838, 10161=>838, 10162=>838, 10163=>838, 10164=>838, 10165=>838, 10166=>838, 10167=>838, 10168=>838, 10169=>838, 10170=>838, 10171=>838, + 10172=>838, 10173=>838, 10174=>838, 10208=>494, 10214=>495, 10215=>495, 10216=>390, 10217=>390, 10218=>556, 10219=>556, 10224=>838, 10225=>838, 10226=>838, 10227=>838, 10228=>1157, 10229=>1434, + 10230=>1434, 10231=>1434, 10232=>1434, 10233=>1434, 10234=>1434, 10235=>1434, 10236=>1434, 10237=>1434, 10238=>1434, 10239=>1434, 10240=>732, 10241=>732, 10242=>732, 10243=>732, 10244=>732, 10245=>732, + 10246=>732, 10247=>732, 10248=>732, 10249=>732, 10250=>732, 10251=>732, 10252=>732, 10253=>732, 10254=>732, 10255=>732, 10256=>732, 10257=>732, 10258=>732, 10259=>732, 10260=>732, 10261=>732, + 10262=>732, 10263=>732, 10264=>732, 10265=>732, 10266=>732, 10267=>732, 10268=>732, 10269=>732, 10270=>732, 10271=>732, 10272=>732, 10273=>732, 10274=>732, 10275=>732, 10276=>732, 10277=>732, + 10278=>732, 10279=>732, 10280=>732, 10281=>732, 10282=>732, 10283=>732, 10284=>732, 10285=>732, 10286=>732, 10287=>732, 10288=>732, 10289=>732, 10290=>732, 10291=>732, 10292=>732, 10293=>732, + 10294=>732, 10295=>732, 10296=>732, 10297=>732, 10298=>732, 10299=>732, 10300=>732, 10301=>732, 10302=>732, 10303=>732, 10304=>732, 10305=>732, 10306=>732, 10307=>732, 10308=>732, 10309=>732, + 10310=>732, 10311=>732, 10312=>732, 10313=>732, 10314=>732, 10315=>732, 10316=>732, 10317=>732, 10318=>732, 10319=>732, 10320=>732, 10321=>732, 10322=>732, 10323=>732, 10324=>732, 10325=>732, + 10326=>732, 10327=>732, 10328=>732, 10329=>732, 10330=>732, 10331=>732, 10332=>732, 10333=>732, 10334=>732, 10335=>732, 10336=>732, 10337=>732, 10338=>732, 10339=>732, 10340=>732, 10341=>732, + 10342=>732, 10343=>732, 10344=>732, 10345=>732, 10346=>732, 10347=>732, 10348=>732, 10349=>732, 10350=>732, 10351=>732, 10352=>732, 10353=>732, 10354=>732, 10355=>732, 10356=>732, 10357=>732, + 10358=>732, 10359=>732, 10360=>732, 10361=>732, 10362=>732, 10363=>732, 10364=>732, 10365=>732, 10366=>732, 10367=>732, 10368=>732, 10369=>732, 10370=>732, 10371=>732, 10372=>732, 10373=>732, + 10374=>732, 10375=>732, 10376=>732, 10377=>732, 10378=>732, 10379=>732, 10380=>732, 10381=>732, 10382=>732, 10383=>732, 10384=>732, 10385=>732, 10386=>732, 10387=>732, 10388=>732, 10389=>732, + 10390=>732, 10391=>732, 10392=>732, 10393=>732, 10394=>732, 10395=>732, 10396=>732, 10397=>732, 10398=>732, 10399=>732, 10400=>732, 10401=>732, 10402=>732, 10403=>732, 10404=>732, 10405=>732, + 10406=>732, 10407=>732, 10408=>732, 10409=>732, 10410=>732, 10411=>732, 10412=>732, 10413=>732, 10414=>732, 10415=>732, 10416=>732, 10417=>732, 10418=>732, 10419=>732, 10420=>732, 10421=>732, + 10422=>732, 10423=>732, 10424=>732, 10425=>732, 10426=>732, 10427=>732, 10428=>732, 10429=>732, 10430=>732, 10431=>732, 10432=>732, 10433=>732, 10434=>732, 10435=>732, 10436=>732, 10437=>732, + 10438=>732, 10439=>732, 10440=>732, 10441=>732, 10442=>732, 10443=>732, 10444=>732, 10445=>732, 10446=>732, 10447=>732, 10448=>732, 10449=>732, 10450=>732, 10451=>732, 10452=>732, 10453=>732, + 10454=>732, 10455=>732, 10456=>732, 10457=>732, 10458=>732, 10459=>732, 10460=>732, 10461=>732, 10462=>732, 10463=>732, 10464=>732, 10465=>732, 10466=>732, 10467=>732, 10468=>732, 10469=>732, + 10470=>732, 10471=>732, 10472=>732, 10473=>732, 10474=>732, 10475=>732, 10476=>732, 10477=>732, 10478=>732, 10479=>732, 10480=>732, 10481=>732, 10482=>732, 10483=>732, 10484=>732, 10485=>732, + 10486=>732, 10487=>732, 10488=>732, 10489=>732, 10490=>732, 10491=>732, 10492=>732, 10493=>732, 10494=>732, 10495=>732, 10502=>838, 10503=>838, 10506=>838, 10507=>838, 10560=>683, 10561=>683, + 10702=>838, 10703=>1000, 10704=>1000, 10705=>1000, 10706=>1000, 10707=>1000, 10708=>1000, 10709=>1000, 10731=>494, 10752=>1000, 10753=>1000, 10754=>1000, 10764=>1325, 10765=>521, 10766=>521, 10767=>521, + 10768=>521, 10769=>521, 10770=>521, 10771=>521, 10772=>521, 10773=>521, 10774=>521, 10775=>521, 10776=>521, 10777=>521, 10778=>521, 10779=>521, 10780=>521, 10877=>838, 10878=>838, 10879=>838, + 10880=>838, 10881=>838, 10882=>838, 10883=>838, 10884=>838, 10885=>838, 10886=>838, 10887=>838, 10888=>838, 10889=>838, 10890=>838, 10891=>838, 10892=>838, 10893=>838, 10894=>838, 10895=>838, + 10896=>838, 10897=>838, 10898=>838, 10899=>838, 10900=>838, 10901=>838, 10902=>838, 10903=>838, 10904=>838, 10905=>838, 10906=>838, 10907=>838, 10908=>838, 10909=>838, 10910=>838, 10911=>838, + 10912=>838, 10926=>838, 10927=>838, 10928=>838, 10929=>838, 10930=>838, 10931=>838, 10932=>838, 10933=>838, 10934=>838, 10935=>838, 10936=>838, 10937=>838, 10938=>838, 11001=>838, 11002=>838, + 11008=>838, 11009=>838, 11010=>838, 11011=>838, 11012=>838, 11013=>838, 11014=>838, 11015=>838, 11016=>838, 11017=>838, 11018=>838, 11019=>838, 11020=>838, 11021=>838, 11022=>836, 11023=>836, + 11024=>836, 11025=>836, 11026=>945, 11027=>945, 11028=>945, 11029=>945, 11030=>769, 11031=>769, 11032=>769, 11033=>769, 11034=>945, 11040=>869, 11041=>873, 11042=>873, 11043=>873, 11360=>557, + 11361=>278, 11362=>557, 11363=>603, 11364=>695, 11365=>613, 11366=>392, 11367=>752, 11368=>634, 11369=>656, 11370=>579, 11371=>685, 11372=>525, 11380=>592, 11381=>654, 11382=>568, 11383=>660, + 61960=>781, 62047=>592, 63173=>612, 64256=>722, 64257=>646, 64258=>646, 64259=>1000, 64260=>1000, 64261=>686, 64262=>861, 64275=>1202, 64276=>1202, 64277=>1196, 64278=>1186, 64279=>1529, 64285=>296, + 64287=>494, 64288=>636, 64297=>838, 64298=>799, 64299=>799, 64300=>799, 64301=>799, 64302=>663, 64303=>663, 64304=>663, 64305=>655, 64306=>454, 64307=>607, 64308=>690, 64309=>336, 64310=>437, + 64311=>1000, 64312=>683, 64313=>336, 64314=>642, 64315=>666, 64316=>635, 64318=>736, 64320=>456, 64321=>771, 64323=>651, 64324=>666, 64326=>639, 64327=>688, 64328=>642, 64329=>799, 64330=>726, + 64331=>272, 64332=>655, 64333=>666, 64334=>666, 65024=>0, 65025=>0, 65026=>0, 65027=>0, 65028=>0, 65029=>0, 65030=>0, 65031=>0, 65032=>0, 65033=>0, 65034=>0, 65035=>0, + 65036=>0, 65037=>0, 65038=>0, 65039=>0, 65533=>1025}; + font[:enc]=''; + font[:diff]=''; + font[:file]='DejaVuSans-Oblique.z'; + font[:ctg]='DejaVuSans-Oblique.ctg.z'; + font[:originalsize]=461680; +end diff --git a/lib/plugins/rfpdf/lib/fonts/freefont/AUTHORS b/lib/plugins/rfpdf/lib/fonts/freefont/AUTHORS new file mode 100644 index 000000000..e10fa42ca --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freefont/AUTHORS @@ -0,0 +1,143 @@ +-*-text-*- +$Id: AUTHORS,v 1.5 2003/10/08 12:22:24 peterlin Exp $ + +The free UCS scalable font collection is being maintained by Primo¾ +Peterlin . The folowing list +cites the other contributors that contributed to particular ISO 10646 +blocks. + +# URW++ Design & Development GmbH + + Basic Latin (U+0041-U+007A) + Latin-1 Supplement (U+00C0-U+00FF) (most) + Latin Extended-A (U+0100-U+017F) + Spacing Modifier Letters (U+02B0-U+02FF) + Mathematical Operators (U+2200-U+22FF) (parts) + Block Elements (U+2580-U+259F) + Dingbats (U+2700-U+27BF) + +# Yannis Haralambous and John + Plaice + + Latin Extended-B (U+0180-U+024F) + IPA Extensions (U+0250-U+02AF) + Greek (U+0370-U+03FF) + Armenian (U+0530-U+058F) + Hebrew (U+0590-U+05FF) + Arabic (U+0600-U+06FF) + Currency Symbols (U+20A0-U+20CF) + Arabic Presentation Forms-A (U+FB50-U+FDFF) + Arabic Presentation Forms-B (U+FE70-U+FEFF) + +# Young U. Ryu + + Arrows (U+2190-U+21FF) + Mathematical Symbols (U+2200-U+22FF) + +# Valek Filippov + + Cyrillic (U+0400-U+04FF) + +# Wadalab Kanji Comittee + + Hiragana (U+3040-U+309F) + Katakana (U+30A0-U+30FF) + +# Angelo Haritsis + + Greek (U+0370-U+03FF) + +# Yannis Haralambous and Virach Sornlertlamvanich + + Thai (U+0E00-U+0E7F) + +# Shaheed R. Haque + + Bengali (U+0980-U+09FF) + +# Sam Stepanyan + + Armenian (U+0530-U+058F) + +# Mohamed Ishan + + Thaana (U+0780-U+07BF) + +# Sushant Kumar Dash + + Oriya (U+0B00-U+0B7F) + +# Harsh Kumar + + Devanagari (U+0900-U+097F) + Bengali (U+0980-U+09FF) + Gurmukhi (U+0A00-U+0A7F) + Gujarati (U+0A80-U+0AFF) + +# Prasad A. Chodavarapu + + Telugu (U+0C00-U+0C7F) + +# Frans Velthuis and Anshuman Pandey + + + Devanagari (U+0900-U+097F) + +# Hardip Singh Pannu + + Gurmukhi (U+0A00-U+0A7F) + +# Jeroen Hellingman + + Oriya (U+0B00-U+0B7F) + Malayalam (U+0D00-U+0D7F) + +# Thomas Ridgeway + + Tamil (U+0B80-U+0BFF) + +# Berhanu Beyene <1beyene AT informatik.uni-hamburg.de>, + Prof. Dr. Manfred Kudlek , Olaf + Kummer , and Jochen Metzinger < + + Ethiopic (U+1200-U+137F) + +# Maxim Iorsh + + Hebrew (U+0590-U+05FF) + + +# Vyacheslav Dikonov + + Syriac (U+0700-U+074A) + Braille (U+2800-U+28FF) + +# M.S. Sridhar + + Devanagari (U+0900-U+097F) + Bengali (U+0980-U+09FF) + Gurmukhi (U+0A00-U+0A7F) + Gujarati (U+0A80-U+0AFF) + Oriya (U+0B00-U+0B7F) + Tamil (U+0B80-U+0BFF) + Telugu (U+0C00-U+0C7F) + Kannada (U+0C80-U+0CFF) + Malayalam (U+0D00-U+0D7F) + +# DMS Electronics, The Sri Lanka Tipitaka Project, and Noah Levitt + + + Sinhala (U+0D80-U+0DFF) + +# Dan Shurovich Chirkov + + Cyrillic (U+0400-U+04FF) + +# Abbas Izad + + Arabic (U+0600-U+06FF) + Arabic Presentation Forms-A (U+FB50-U+FDFF) + Arabic Presentation Forms-B (U+FE70-U+FEFF) + +Please see the CREDITS file for details on who contributed particular +subsets of the glyphs in font files. diff --git a/lib/plugins/rfpdf/lib/fonts/freefont/CREDITS b/lib/plugins/rfpdf/lib/fonts/freefont/CREDITS new file mode 100644 index 000000000..4fb088b6f --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freefont/CREDITS @@ -0,0 +1,389 @@ +-*-text-*- +$Id: CREDITS,v 1.4 2003/03/27 08:40:03 peterlin Exp $ + +This file lists the contributors and contributions to the free UCS +scalable font project. + + +# URW++ Design & Development GmbH + +URW++ donated a set of 35 core PostScript Type 1 fonts to the +Ghostscript project , to be available +under the terms of GNU General Public License (GPL). + + Basic Latin (U+0041-U+007A) + Latin-1 Supplement (U+00C0-U+00FF) + Latin Extended-A (U+0100-U+017F) + Spacing Modifier Letters (U+02B0-U+02FF) + Mathematical Operators (U+2200-U+22FF) + Block Elements (U+2580-U+259F) + Dingbats (U+2700-U+27BF) + + +# Yannis Haralambous and John + Plaice + +Yannis Haralambous and John Plaice are the authors of Omega +typesetting system, . Omega is an +extension of TeX. Its first release, aims primarily at improving TeX's +multilingual abilities. In Omega all characters and pointers into +data-structures are 16-bit wide, instead of 8-bit, thereby eliminating +many of the trivial limitations of TeX. Omega also allows multiple +input and output character sets, and uses programmable filters to +translate from one encoding to another, to perform contextual +analysis, etc. Internally, Omega uses the universal 16-bit Unicode +standard character set, based on ISO-10646. These improvements not +only make it a lot easier for TeX users to cope with multiple or +complex languages, like Arabic, Indic, Khmer, Chinese, Japanese or +Korean, in one document, but will also form the basis for future +developments in other areas, such as native color support and +hypertext features. ... Fonts for UT1 (omlgc family) and UT2 (omah +family) are under development: these fonts are in PostScript format +and visually close to Times and Helvetica font families. (from the +Omega WWW site). Omega fonts are available subject to GPL +. + + Latin Extended-B (U+0180-U+024F) + IPA Extensions (U+0250-U+02AF) + Greek (U+0370-U+03FF) + Armenian (U+0530-U+058F) + Hebrew (U+0590-U+05FF) + Arabic (U+0600-U+06FF) + Currency Symbols (U+20A0-U+20CF) + Arabic Presentation Forms-A (U+FB50-U+FDFF) + Arabic Presentation Forms-B (U+FE70-U+FEFF) + + +# Valek Filippov + +Valek Filippov added Cyrillic glyphs and composite Latin Extended A to +the whole set of the abovementioned URW set of 35 PostScript core +fonts, . The fonts are available under +GPL. + + Latin Extended-A (U+0100-U+017F) + Cyrillic (U+0400-U+04FF) + + +# Wadalab Kanji Comittee + +Between April 1990 and March 1992, Wadalab Kanji Comittee put together +a series of scalable font files with Japanese scripts, in four forms: +Sai Micho, Chu Mincho, Cho Kaku and Saimaru. The font files are +written in custom file format, while tools for conversion into +Metafont and PostScript Type 1 are also supplied. The Wadalab Kanji +Comittee has later been dismissed, and the resulting files can be now +found on the FTP server of the Depertment of Mathematical Engineering +and Information Physics, Faculty of Engineering, University of Tokyo +. + + Hiragana (U+3040-U+309F) + Katakana (U+30A0-U+30FF) + + +# Young U. Ryu + +Young Ryu is the author of Txfonts, a set of mathematical symbols +designed to accompany text typeset in Times or its variants. In the +documentation, Young adresses the design of mathematical symbols: "The +Adobe Times fonts are thicker than the CM fonts. Designing math fonts +for Times based on the rule thickness of Times = , , + , / , < , +etc. would result in too thick math symbols, in my opinion. In the TX +fonts, these glyphs are thinner than those of original Times +fonts. That is, the rule thickness of these glyphs is around 85% of +that of the Times fonts, but still thicker than that of the CM fonts." +TX fonts are are distributed under the GNU public license +(GPL). Pointers to their location are available on +. + + Arrows (U+2190-U+21FF) + Mathematical Symbols (U+2200-U+22FF) + + +# Angelo Haritsis + +Angelo Haritsis has compiled a set of Greek Type 1 fonts, available on +. +The glyphs from this source has been used to compose Greek glyphs in +FreeSans and FreeMono. + +Angelo's licence says: "You can enjoy free use of these fonts for +educational or commercial purposes. All derived works should include +this paragraph. If you want to change something please let me have +your changes (via email) so that they can go into the next +version. You can also send comments etc to the above address." + + Greek (U+0370-U+03FF) + + +# Yannis Haralambous and Virach Sornlertlamvanich + +In 1999, Yannis Haralambous and Virach Sornlertlamvanich made a set of +glyphs covering the Thai national standard NF3, in both upright and +slanted shape. The collection of glyphs have been made part of GNU +intlfonts 1.2 package and is available on + under GPL. + + Thai (U+0E00-U+0E7F) + + +# Shaheed R. Haque + +Shaheed Haque has developed a basic set of basic Bengali glyphs +(without ligatures), using ISO10646 encoding. They are available under +the XFree86 license at . + +Copyright (C) 2001 S.R.Haque . All Rights Reserved. + +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 S.R.HAQUE 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. + +Except as contained in this notice, the name of S.R.Haque shall not be +used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from +S.R.Haque. + + Bengali (U+0980-U+09FF) + + +# Sam Stepanyan + +Sam Stepanyan created a set of Armenian sans serif glyphs visually +compatible with Helvetica or Arial. Available on +. On +2002-01-24, Sam writes: "Arial Armenian font is free for +non-commercial use, so it is OK to use under GPL license." + + Armenian (U+0530-U+058F) + + +# Mohamed Ishan + +Mohamed Ishan has started a Thaana Unicode Project + and among other things created a +couple of Thaana fonts, available under FDL or BDF license. + + Thaana (U+0780-U+07BF) + + +# Sushant Kumar Dash (*) + +Sushant Dash has created a font in his mother tongue, Oriya. As he +states on his web page : +"Please feel free to foreword this mail to your Oriya friends. No +copyright law is applied for this font. It is totally free!!! Feel +free to modify this using any font editing tools. This is designed for +people like me, who are away from Orissa and want to write letters +home using Computers, but suffer due to unavailability of Oriya +fonts.(Or the cost of the available packages are too much)." + + Oriya (U+0B00-U+0B7F) + + +# Harsh Kumar + +Harsh Kumar has started BharatBhasha - +an effort to provide "FREE software, Tutorial, Source Codes +etc. available for working in Hindi, Marathi, Gujarati, Gurmukhi and +Bangla. You can type text, write Web pages or develop Indian Languages +Applications on Windows and on Linux. We also offer FREE help to +users, enthusiasts and software developers for their work in Indian +languages." + + Devanagari (U+0900-U+097F) + Bengali (U+0980-U+09FF) + Gurmukhi (U+0A00-U+0A7F) + Gujarati (U+0A80-U+0AFF) + + +# Prasad A. Chodavarapu + +Prasad A. Chodavarapu created Tikkana, a Telugu font available in Type +1 and TrueType format on . +Tikkana exceeds the Unicode Telugu range with some composite glyphs. +Available under the GNU General Public License. + + Telugu (U+0C00-U+0C7F) + + +# Frans Velthuis and Anshuman Pandey + + +In 1991, Frans Velthuis from the Groningen University, The +Netherlands, released a Devanagari font as Metafont source, available +under the terms of GNU GPL. Later, Anshuman Pandey from the Washington +University, Seattle, USA, took over the maintenance of font. Fonts can +be found on CTAN, . I +converted the font to Type 1 format using Péter Szabó's TeXtrace +program and removed some +redundant control points with PfaEdit. + + Devanagari (U+0900-U+097F) + + +# Hardip Singh Pannu + +In 1991, Hardip Singh Pannu has created a free Gurmukhi TrueType font, +available as regular, bold, oblique and bold oblique form. Its license +says "Please remember that these fonts are copyrighted (by me) and are +for non-profit use only." + + Gurmukhi (U+0A00-U+0A7F) + + +# Jeroen Hellingman + +Jeroen Hellingman created a set of Malayalam metafonts in 1994, and a +set of Oriya metafonts in 1996. Malayalam fonts were created as +uniform stroke only, while Oriya metafonts exist in both uniform and +modulated stroke. From private communication: "It is my intention to +release the fonts under GPL, but not all copies around have this +notice on them." Metafonts can be found on CTAN, + and +. + + Oriya (U+0B00-U+0B7F) + Malayalam (U+0D00-U+0D7F) + + +# Thomas Ridgeway <> (*) + +Thomas Ridgeway, then at the Humanities And Arts Computing Center, +Washington University, Seattle, USA, (now defunct), created a Tamil +metafont in 1990. Anshuman Pandey from the same university took over +the maintenance of font. Fonts can be found at CTAN, +. + + Tamil (U+0B80-U+0BFF) + + +# Berhanu Beyene <1beyene AT informatik.uni-hamburg.de>, + Prof. Dr. Manfred Kudlek , Olaf + Kummer , and Jochen Metzinger < + +Beyene, Kudlek, Kummer and Metzinger from the Theoretical Foundations +of Computer Science, University of Hamburg, prepared a set of Ethiopic +metafonts, found on +. They also +maintain home page on the Ethiopic font project, +, +and can be reached at . The current +version of fonts is 0.7 (1998), and they are released under GNU GPL. I +converted the fonts to Type 1 format using Péter Szabó's TeXtrace +program and removed some +redundant control points with PfaEdit. + + Ethiopic (U+1200-U+137F) + + +# Maxim Iorsh + +In 2002, Maxim Iorsh started the Culmus project, aiming at providing +Hebrew-speaking Linux and Unix community with a basic collection of +Hebrew fonts for X Windows. The fonts are visually compatible with +URW++ Century Schoolbook L, URW++ Nimbus Sans L and URW++ Nimbus Mono +L families, respectively, and are released under GNU GPL license. See +also . + + Hebrew (U+0590-U+05FF) + + +# Vyacheslav Dikonov + +Vyacheslav Dikonov made a braille unicode font that could be merged +with the UCS fonts to fill the 2800-28FF range completely. (uniform +scaling is possible to adapt it to any cell size). He also contributed +a free syriac font, whose glyphs (about half of them) are borrowed +from the "Carlo Ator" font freely downloadable from +. Vyacheslav also filled in a few missing +spots in the U+2000-U+27FF area, e.g. the box drawing section, sets of +subscript and superscript digits and capital Roman numbers. + + Syriac (U+0700-U+074A) + Box Drawing (U+2500-U+257F) + Braille (U+2800-U+28FF) + + +# M.S. Sridhar + +M/S Cyberscape Multimedia Limited, Mumbai, developers of Akruti +Software for Indian Languages (http://www.akruti.com/), have released +a set of TTF fonts for nine Indian scripts (Devanagari, Gujarati, +Telugu, Tamil, Malayalam, Kannada, Bengali, Oriya, and Gurumukhi) +under the GNU General Public License (GPL). You can download the fonts +from the Free Software Foundation of India WWW site +(http://www.gnu.org.in/software/software.html#akruti) or from the +Akruti website. + +For any further information or assistance regarding these fonts, +please contact mssridhar AT vsnl.com. + + Devanagari (U+0900-U+097F) + Bengali (U+0980-U+09FF) + Gurmukhi (U+0A00-U+0A7F) + Gujarati (U+0A80-U+0AFF) + Oriya (U+0B00-U+0B7F) + Tamil (U+0B80-U+0BFF) + Telugu (U+0C00-U+0C7F) + Kannada (U+0C80-U+0CFF) + Malayalam (U+0D00-U+0D7F) + + +# DMS Electronics, The Sri Lanka Tipitaka Project, and Noah Levitt + + +Noah Levitt found out that the Sinhalese fonts available on the site + are released under GNU GPL, or, +precisely, "Public Domain under GNU Licence + Produced by DMS +Electronics for The Sri Lanka Tipitaka Project" (taken from the font +comment), and took the effort of recoding the font to Unicode. + + Sinhala (U+0D80-U+0DFF) + + +# Daniel Shurovich Chirkov + +Dan Chirkov updated the FreeSerif font with the missing Cyrillic +glyphs needed for conformance to Unicode 3.2. The effort is part of +the Slavjanskij package for Mac OS X, +. + + Cyrillic (U+0400-U+04FF) + + +# Primo¾ Peterlin + +Primo¾ Peterlin filled in missing glyphs here and there (e.g. Latin +Extended-B and IPA Extensions ranges in the FreeMono familiy), and +created the following UCS blocks: + + Latin Extended-B (U+0180-U+024F) + IPA Extensions (U+0250-U+02AF) + Arrows (U+2190-U+21FF) + Box Drawing (U+2500-U+257F) + Block Elements (U+2580-U+259F) + Geometrical Shapes (U+25A0-U+25FF) + + +Notes: + +*: The glyph collection looks license-compatible, but its author has + not yet replied and agreed on his/her work being used in part of + this glyph collection. diff --git a/lib/plugins/rfpdf/lib/fonts/freefont/ChangeLog b/lib/plugins/rfpdf/lib/fonts/freefont/ChangeLog new file mode 100644 index 000000000..a04f78b38 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freefont/ChangeLog @@ -0,0 +1,630 @@ +2003-10-08 Primoz Peterlin + + # FreeMonoOblique.sfd, FreeSerifBoldItalic.sfd, + FreeSerifItalic.sfd - applied Josef Segur's corrections from + Oct. 5. + +2003-10-02 Primoz Peterlin + + # sfd/FreeSerif.sfd - Abbas Izad's contributed Arabic/Farsi + characters added. + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd, + sfd/FreeSerifBoldItalic.sfd - Combining characters (U+0300 - + U+036F) moved left, so that they have negative horizontal values + and zero advance width. + +2003-09-15 Primoz Peterlin + + # sfd/FreeSerifBold.sfd, sfd/FreeSerifItalic.sfd - Started working + on super- and subscripts. + +2003-09-12 Primoz Peterlin + + # sfd/FreeSans.sfd, sfd/FreeSerif.sfd - Added some missing + Hiragana and Katakana characters. + + # sfd/FreeSansBold.sfd - Cleared background characters in Latin + Extended-A. Added some automatically constructed characters in + Latin Extended-B. Started with superscripts and subscripts. + + # sfd/FreeSans.sfd - Subscript numerals (U+2080-U+2089) completed. + +2003-05-19 Primoz Peterlin + + # sfd/FreeSerif.sfd - Thai characters po pla and bo baimai + swapped; Thai character fongman corrected; all courtesy Theppitak + Karoonboonyanan. + +2003-05-17 Panayotis Katsaloulis + + # sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd, + sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - Full support + of all ancient greek glyphs + +2003-05-15 Primoz Peterlin + + # tools/KerningNumerals.pl - A Perl script for moving kerning + information from ASCII numerals (U+0030...) to characters in the + Adobe corporate use area (U+F6xx). + + # sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd, + sfd/FreeSansBoldOblique.sfd - Created kerned numerals in the Adobe + corporate use area (U+F6xx) and moved kerning information from + ASCII numerals to the kerned numerals. + +2003-05-14 Primoz Peterlin + + # sfd/FreeSans.sfd - First approximation of super- and subscript + numerals and vulgar fractions. + + # sfd/FreeSerif.sfd - Super- and subscript numerals complete, + vulgar fractions completed and redone as references rather than + outlines. + +2003-05-12 Primoz Peterlin + + # sfd/FreeSerif.sfd - Clean-up of the Cyrillic letters added on + March 27; super- and subscripts, vulgar fractions. + +2003-05-09 Primoz Peterlin + + # sfd/FreeMonoBold.sfd - Added a couple of characters to + the Latin Extended-B area and the IPA extensions area. + +2003-05-08 Primoz Peterlin + + # sfd/FreeSerifBoldItalic.sfd - Added a couple of characters to + the Latin Extended-B area. + + # sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd, + sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - ASCII + numerals now monospaced; kerned numerals moved to Adobe corporate + use area + (U+F6xx). + +2003-05-07 Primoz Peterlin + + # sfd/FreeSerif.sfd - Roman numerals now more complete. + + # sfd/FreeSansOblique.sfd, sfd/FreeSansBoldOblique.sfd - Accented + characters added in the Latin Extended-B area. + + # sfd/FreeSans.sfd - Greek accents added in the Greek Extended + area, characters added in the Latin Extended-B area, Roman + numerals added. + + # sfd/FreeMonoOblique.sfd - Kerning pairs removed (what were they + doing in a monospaced font, anyway?). + + # sfd/FreeMonoBoldOblique.sfd - Additions in Latin Extended-B and + Basic Greek. + + # sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd, sfd/FreeMonoOblique.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd, + sfd/FreeSansBoldOblique.sfd - Major cleanup (fixed widths, open + paths, path directions (clockwise/counter-clockwise), points + rounded to integer values; outlines simplified etc.) + +2003-05-06 Primoz Peterlin + + # tools/OS2UnicodeRange - A simple script to display OS/2 Unicode + range table in TrueType fonts. + + # sfd/FreeSans.sfd, sfd/FreeSansBold.sfd - ASCII numerals now + monospaced; kerned numerals moved to Adobe corporate use area + (U+F6xx). FreeSans is done, FreeSansBold half-way. + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd, + sfd/FreeSerifBoldItalic.sfd - Added 2003 in copyright info. + +2003-03-27 Primoz Peterlin + + # sfd/FreeSerif.sfd - Cyrillic and Cyrillic Supplement blocks + brought to conformance with Unicode 3.2, courtesy Daniel Shurovich + Chirkov. + +2003-03-19 Primoz Peterlin + + # sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd - somewhat wider + germandbls (U+00DF), due to complaints by Walter Schmidt. + +2003-03-18 Primoz Peterlin + + # sfd/FreeSans.sfd - Added Sinhala glyphs from the Tipitaka + project , recoded to Unicode by Noah Levitt. + +2003-02-19 Primoz Peterlin + + # sfd/FreeSans.sfd - Minor changes on mathematical operators. + +2003-02-18 Primoz Peterlin + + # sfd/FreeMono.sfd - minor cleanup of glyph backgrounds; changed + integral signs (U+222B - U+2230) + +2003-02-05 Primoz Peterlin + + # sfd/FreeSans.sfd - added a couple of glyphs in the IPA and + African Latin ranges. + +2003-01-30 Primoz Peterlin + + # sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd - Corrected Maltese Hbar (U+0126) + and/or hbar (U+0127). + +2003-01-28 Primoz Peterlin + + # sfd/FreeSerifItalic.sfd - Corrected Maltese hbar (U+0127). + +2002-12-18 Primoz Peterlin + + # tools/ConvertFont - PfaEdit script for converting SFD files to + TrueType fonts. + + # sfd/FreeSans.sfd - Added Tamil and Kannada glyphs from the + Akruti Indic fonts. + +2002-12-17 Primoz Peterlin + + # sfd/FreeSans.sfd - Added Devanagari and Gujarati glyphs from the + Akruti Indic fonts. + + # www/index.html - Added information on Rogier van Dalen's tools. + + # AUTHORS - Added M.S. Sridhar. + + # CREDITS - Correct spelling of Culmus project. Added M.S. Sridhar. + +2002-12-06 Primoz Peterlin + + # sfd/FreeMono.sfd - Added Braille glyphs, courtesy Vyacheslav + Dikonov. + + # sfd/FreeSans.sfd - Added Unicode Syriac glyphs, courtesy + Vyacheslav Dikonov. + +2002-10-11 Primoz Peterlin + + # www/index.html - Added information on the availability of the + Debian GNU/Linux package. + + # sfd/FreeSerif.sfd, sfd/FreeSans.sfd - added some kern pairs + beyond Latin-1 area. + + # sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd, + sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - re-introduced + all the emtpy glyph slots (changes from Sep 23 made PfaEdit + crash). + +2002-09-23 Primoz Peterlin + + # sfd/FreeSerif.sfd, sfd/FreeSerifItalic.sfd, + sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd - imported + kerning information from the URW++ AFM files + +2002-09-11 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoOblique.sfd - updated Hebrew parts to comply with + Culmus v0.6. + + # sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansOblique.sfd - Added Danilo Segan's Serbian Cyrillic + glyphs; updated Hebrew parts to comply with Culmus v0.6. + +2002-09-09 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansOblique.sfd - Updated Cyrillic part to match + Filippov's 1.0.7pre14 + + # sfd/FreeSansOblique.sfd - added Sam Stepanyan's Armenian glyphs + from FreeSans (skewed for 12 degrees). + +2002-09-06 Primoz Peterlin + + # sfd/FreeSans.sfd, sfd/FreeSansOblique.sfd, + sfd/FreeSansBold.sfd, sfd/FreeSansOblique.sfd - Added Maxim + Iorsh's Hebrew characters. + +2002-08-29 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, + sfd/FreeMonoBold.sfd, sfd/FreeMonoOblique.sfd - Added Maxim + Iorsh's Hebrew characters. + + # AUTHORS, CREDITS - Added Maxim Iorsh as author. + +2002-08-28 Primoz Peterlin + + # www/index.html - Added information of Microsoft's withdrawal of + freely available Unicode TrueType fonts + + # www/resources.html - Added link to Maxim Iorsh's Culmus project. + +2002-07-26 Primoz Peterlin + + # sfd/FreeMono.sfd - Added a couple of characters (Arrows area). + +2002-06-11 Primoz Peterlin + + # sfd/FreeMono.sfd - Applied Michalis Kabrianis's patch concerning + perispomeni in Greek politoniko. + +2002-05-23 Primoz Peterlin + + # sfd/FreeMono.sfd - Applied Michalis Kabrianis's patch concerning + psili in Greek politoniko. Also added two working variants of + chars in the IPA range. + +2002-05-15 Primoz Peterlin + + # sfd/FreeSans.sfd, sfd/FreeSansBold.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifBold.sfd - Deleted explicit ".notdef" character with + no contours. + +2002-05-14 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd, + sfd/FreeSerifBoldItalic.sfd - The new version of PfaEdit saves + correctly formed Panose and LineGap lines. + + # sfd/FreeSansBoldOblique.sfd - Filled-in the missing TTFWidth and + TTFWeight values. + +2002-05-09 Primoz Peterlin + + # sfd/FreeSans.sfd - Added diacritics to the Spacing Modifier + Letters and Combining Diacritical Marks areas. Added composed + glyphs to the Latin Extended-B area. + +2002-05-07 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd, + sfd/FreeSerifBoldItalic.sfd - Updated Panose information with data + provided by Josef W. Segur. Updated TTF headers with English and + Slovenian text. + +2002-04-30 Primoz Peterlin + + # sfd/FreeMonoBold.sfd - Working on Greek small letters. Several + minor changes (lower carons etc.) + +2002-04-29 Primoz Peterlin + + # FreeMonoBoldOblique.sfd - Started adding Greek. + + # sfd/FreeMonoBold.sfd - Added glyphs in the Geometrical Shapes + and Miscellaneous Symbols area. Harmonizing Greek with Latin. Done + with capitals. + + # sfd/FreeMono.sfd - Deleted the explicit .notdef character. Added + one glyph to the Geometrical Shapes area, which is now completed; + added three glyphs to the Miscellaneous Symbols area. Harmonizing + Greek with Latin. Done with the capitals. + +2002-04-26 Primoz Peterlin + + # sfd/FreeSans.sfd - Adjusted accent positions on several glyphs + in the Latin Extended-A area. + +2002-04-25 Primoz Peterlin + + # sfd/FreeMonoBold.sfd - Box Drawing area completed. Added a + couple of glyphs in the Geometrical Shapes area. + + # sfd/FreeMono.sfd - Small corrections in the Box Drawing area. + +2002-04-24 Primoz Peterlin + + # sfd/FreeMono.sfd - Box Drawing area completed. + +2002-04-23 Primoz Peterlin + + # tools/WGL4.lst - corrected. + + # sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd - Working on Box Drawing + area. + +2002-04-22 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoBold.sfd - Working on Latin + Extended-B and Greek. + +2002-04-19 Primoz Peterlin + + # sfd/FreeSerif.sfd - Somewhat cleaner chess figures. + + # tools/MES-2.txt, tools/MES-2.lst - Corrected list (it is not + 203C-203E, it is 203C and 203E). + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd, sfd/FreeSans.sfd, + sfd/FreeSansOblique.sfd, sfd/FreeSansBold.sfd, + sfd/FreeSansBoldOblique.sfd, sfd/FreeSerif.sfd, + sfd/FreeSerifItalic.sfd, sfd/FreeSerifBold.sfd, + sfd/FreeSerifBoldItalic.sfd - Changed "Family Name" from Free to + FreeSerif, FreeSans and FreeMono, as appropriate. Changed Font + Modifiers from MonoBold etc. to Bold, Italic, Oblique, BoldOblique + and BoldItalic. + +2002-04-18 Primoz Peterlin + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd, sfd/FreeMonoBold.sfd, + sfd/FreeMonoBoldOblique.sfd - Corrected metrics; now all character + widths are set to 600. + +2002-04-17 Primoz Peterlin + + # sfd/FreeSerif.sfd - Corrected glyphs in the Box Drawing area and + Block Elements area, which should extend through the ascender#and + descender# height. + + # sfd/FreeMonoBold.sfd - Continued working on harmonizing Greek + letters with Latin and Cyrillic. + + # sfd/FreeMonoBold.sfd - Added some box drawing characters. + +2002-04-16 Primoz Peterlin + + # www/design-notes.html - Updated notes on stroke width for + symbols in Free Mono Bold. + + # sfd/FreeMono.sfd - Added a handful of characters in the + Miscellaneous Symbols area. + + # sfd/FreeMonoBoldOblique.sfd - Added subscripts, superscripts and + vulgar fractions. + + # sfd/FreeMonoBold.sfd - Started harmonizing Greek letters with + Latin and Cyrillic. + + # sfd/FreeMonoBold.sfd - Added subscripts, superscripts and vulgar + fractions. + +2002-04-15 Primoz Peterlin + + # www/design-notes.html - Updated notes on super-/subscripts in + Free Mono Bold. Separate subsections for Free Mono regular and + Free Mono Bold. + +2002-04-12 Primoz Peterlin + + # sfd/FreeSerif.sfd - Added Ethiopian glyphs, converted from the + Metafont sources from TGI, Universität Hamburg (authors Berhanu + Beyene, Prof. Dr. Manfred Kudlek, Olaf Kummer, and Jochen + Metzinger) using Szabo's TeXtrace and retouched using + PfaEdit. Ethiopian metafonts are released under GNU GPL, + . + + # sfd/FreeMonoBold.sfd - Added 40 characters, mostly in the Latin + Extended-B and IPA Extensions areas. + +2002-04-11 Primoz Peterlin + + # sfd/FreeMono.sfd - Added a handful of characters in the Latin + Extended-B, IPA Extensions, Currency Symbols and Miscellaneous + Symbols areas. + +2002-04-09 Primoz Peterlin + + # sfd/FreeMono.sfd - Correcting accent positioning in the Extended + Greek area; adding a couple of characters here and there. Still 20 + characters short of MES-2 conformance. + +2002-04-08 Primoz Peterlin + + # sfd/FreeMono.sfd - Added some characters in the Arrows area; + more or less completed Extended Greek area (accents still need to + be fine-tuned). + +2002-04-05 Primoz Peterlin + + # sfd/FreeMono.sfd - Modern non-Russian Cyrilic mostly completed. + + # sfd/FreeMonoOblique.sfd - Synchronized with FreeMono. + + # sfd/FreeSerif.sfd - Added Thomas Ridgeway's Tamil characters + (converted from Metafont and edited somehwat). + +2002-04-04 Primoz Peterlin + + # sfd/FreeMonoOblique.sfd - Armenian letters added. + + # sfd/FreeMonoBold.sfd - Serbian Cyrillic letters dje, tshe, lje + and nje corrected. + + # sfd/FreeMono.sfd - Serbian Cyrillic letters dje and tshe + corrected. Some other non-Russian Cyrillic letters modified and + "welded together". + +2002-04-03 Primoz Peterlin + + # sfd/FreeMono.sfd - Added more or less complete Armenian + area. The glyphs are a tidied-up version based on the Armenian + Courier on the . Now we have + 1673 characters. + +2002-03-28 Primoz Peterlin + + # sfd/FreeMono.sfd - Added some mathematical symbols. + +2002-03-26 Primoz Peterlin + + # sfd/FreeSans.sfd - took H.S. Pannu's Gurmukhi from FreeSerif. It + actually fits to FreeSans much better. It seems I'll have to look + for another Gurmukhi font with modulated stroke for FreeSerif. + + # sfd/FreeSerifItalic.sfd - replaced existing Hebrew glyphs by + those from FreeSerif (slanted for 15.5 degrees). + + # sfd/FreeSerif.sfd - Added dotted Hebrew letters. Changed barred H. + + # sfd/FreeMono.sfd - Completed vulgar fractions; minor changes in + Greek; added some mathematical operators. + + # sfd/FreeMonoBold.sfd - added 12 characters to Latin Extended-B + and IPA Extensions areas (total 984). + +2002-03-25 Primoz Peterlin + + # sfd/FreeMonoBold.sfd - started adding Latin Extended-B and IPA + Extensions. + + # sfd/FreeMono.sfd - Minor cosmetic changes; cleaning up Greek + (removing redundant control points), added some non-European + Cyrillic glyphs as a test. + +2002-03-22 Primoz Peterlin + + # sfd/FreeMono.sfd - Some minor modifications; letters in Latin + Extended-B area "welded" together. + +2002-03-20 Primoz Peterlin + + # www/index.html - finally linked the resources and design notes + pages. + + # www/design-notes.html - added scaling information for super- and + subscript numerals in FreeMono. + +2002-03-19 Primoz Peterlin + + # sfd/FreeMono.sfd - the Latin Extended-B and IPA Extension area + characters moved from FreeMono and skewed for 12 degrees. + +2002-03-18 Primoz Peterlin + + # sfd/FreeMono.sfd - added a dozen or two of new characters, in + particular in the Latin Extended-B and IPA Extension area. + +2002-03-15 Primoz Peterlin + + # sfd/FreeMono.sfd - added a dozen of two of new characters, in + particular in the IPA Extension area. + + # www/design-notes.html - Corrected data for x-height in FreeMono; + information on constructing small caps. + +2002-03-14 Primoz Peterlin + + # sfd/FreeMono.sfd - added three smiley characters to the + Miscallaneous Symbols area. + +2002-03-10 Primoz Peterlin + + # sfd/FreeSerif.sfd - Anshuman Pandey has only converted Gurmukhi + from TrueType to Metafont; the original author of Gurkmukhi font + is Hardip Singh Pannu . + Got the permission from him to include the Gurmukhi glyph set. + +2002-03-08 Primoz Peterlin + + # sfd/FreeSerif.sfd - Added some more glyphs in the Mathematical + Symbols area to a total number of 3374. + +2002-03-06 Primoz Peterlin + + # sfd/FreeSerif.sfd - Added a basic Gurmukhi set. + + # www/design-notes.html - started a page on design notes + + # sfd/FreeMono.sfd - realized that glyphs in the Box Drawing area + and Block Elements area should extend through the ascender#and + descender# height, and corrected it. + + # sfd/FreeMono.sfd, sfd/FreeMonoOblique.sfd - added some musical + glyphs, linking "no-break space" to space, "soft hyphen" to + hyphen-minus etc. + +2002-03-05 Primoz Peterlin + + # tools/WGL4.lst - Added Windows Glyph List 4.0 + + # tools/LigatureList.pl - Wrote a Perl script, which lists the + GSUB list (ligature list) of a OpenType font. + + # sfd/FreeSerifBold.sfd, sfd/FreeSerifBoldItalic.sfd, + sfd/FreeSerifItalic.sfd - auxilliary Hebrew glyphs added. They are + too light compared with Latin and will be substituted with better + ones. + +2002-03-04 Primoz Peterlin + + # sfd/FreeSerif.sfd - Added some more glyphs to the Mathematical + Operators area (page 0x22). + + # sfd/FreeSerif.sfd - Incomplete and fragmentary support for + Devanagari, originating from Harsh Kumar's Shusha fonts was + replaced by Frans Velthuis' Devanagari metafont, now maintained by + Anshuman Pandey and available under + GPL. Until I figure out how to provide glyph substitution table in + OpenType, only the Unicode part is there. + +2002-02-28 Primoz Peterlin + + # ChangeLog file created + + # sfd/FreeSerif.sfd - Added some Telugu glyphs to page 0x0C, + courtesy Prasad A. Chodavarapu + + # sfd/FreeSerif.sfd - Added some glyphs to the Miscellaneous + Symbols page (0x26). + +2002-02-26 Primoz Peterlin + + # mailing lists freefont-announce and freefont-bugs created + +2002-02-25 Primoz Peterlin + + # sfd/FreeSerif.sfd - Added a couple of glyphs in Mathematics + Operators area. + + # sfd/FreeMono.sfd + - Added some more glyphs, in particular in the Mathematical + Operators section. + - Changed FamilyName to Free, FontName to FreeMono, and Full name + to "Free Monospaced". + +2002-02-20 Primoz Peterlin + + # sfd/ directory added containing FreeSerif, FreeSans and FreeMono + families. + + # tools/ directory added containing lists with characters required + for MES (Multilinguag European Subset) compliance. + + # tools/mes-list-expand.pl created - a Perl script for expanding MES + ranges into simple one-char-per-line format + + # tools/CheckConformance.pl created - a Perl script for checking + conformance of a font file with a given coded character set + + # homepage created + +2002-02-19 Primoz Peterlin + + # freefont (Free UCS Scalable Fonts) project approved on + savannah.gnu.org: diff --git a/lib/plugins/rfpdf/lib/fonts/freefont/INSTALL b/lib/plugins/rfpdf/lib/fonts/freefont/INSTALL new file mode 100644 index 000000000..1e1e64635 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freefont/INSTALL @@ -0,0 +1,57 @@ +-*-mode:text;-*- +$Id: INSTALL,v 1.1 2002/12/12 15:09:05 peterlin Exp $ + + + Installing the Free UCS outline fonts + ===================================== + + +These installation notes are supposed to provide a helpful guidance +through the process of installation of free UCS outline fonts. They +can probably be significantly improved. Please direct your comments, +suggestions for improvements, criticisms etc. to Primoz PETERLIN + and thus help improve them. + + +1. UNIX/GNU/Linux/BSD Systems + +The rather awkward "UNIX/GNU/Linux/BSD" agglomeration is used to +denote any system capable of running XFree86 server with FreeType +, a high-quality free font rasterizer. + +1.1 The rough way + +Unfortunately, hardly any other way exists at the moment. + +1) Fetch the freefont-ttf.tar.gz package with Free UCS outline fonts + in the TrueType format. + +2) Unpack TrueType fonts into a suitable directory, + e.g. /usr/share/fonts/default/TrueType/. + +3) If you have chosen any other directory, make sure the directory you + used to install the fonts is listed in the path searched by the X + Font Server. Append the directory to the "catalogue=" in the + /etc/X11/fs/config. + +4) Run ttmkfdir in the directory where you unpacked the fonts. + + +1.2 Debian GNU/Linux + +Users of Debian GNU/Linux system will probably want to use the +pre-packed Debian package, as available from the Debian site, +, or +any of its mirrors. You can install them by issuing the command + +apt-get install ttf-freefont + + +2. Microsoft Windows 95/98/NT/2000/XP + +To be written. + + +3. MacOS + +To be written. diff --git a/lib/plugins/rfpdf/lib/fonts/freefont/README b/lib/plugins/rfpdf/lib/fonts/freefont/README new file mode 100644 index 000000000..6f0a3d8d7 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freefont/README @@ -0,0 +1,113 @@ +-*-text-*- +$Id: README,v 1.1 2002/11/28 10:10:30 peterlin Exp $ + +Summary: This project aims to privide a set of free scalable +(PostScript Type0, TrueType, OpenType...) fonts covering the ISO +10646/Unicode UCS (Universal Character Set). + + +Why do we need free scalable UCS fonts? + +A large number of free software users switched from free X11 +bitmapped fonts to proprietary Microsoft Truetype fonts, as a) they +used to be freely downloaded from Microsoft Typography page +, b) they contain a more +or less decent subsed of the ISO 10646 UCS (Universal Character Set), +c) they are high-quality, well hinted scalable Truetype fonts, and d) +Freetype , a free high-quality Truetype font +renderer exists and has been integrated into the latest release of +XFree86, the free X11 server. + +Building a dependence on non-free software, even a niche one like +fonts, is dangerous. Microsoft Truetype core fonts are not free, they +are just costless. For now, at least. Citing the TrueType core fonts +for the Web FAQ : +"You may only redistribute the fonts in their original form (.exe or +.sit.hqx) and with their original file name from your Web site or +intranet site. You must not supply the fonts, or any derivative fonts +based on them, in any form that adds value to commercial products, +such as CD-ROM or disk based multimedia programs, application software +or utilities." As of August 2002, however, the fonts are not +anymore available on the Web, which makes the situation clearer. + +Aren't there any free high-quality scalable fonts? Yes, there are. +URW++, a German digital typefoundry, released their own version of the +35 Postscript Type 1 core fonts under GPL as their donation to the +Ghostscript project . The Wadalab +Kanji comittee has produced Type 1 font files with thousands of +filigree Japanese glyphs . +Yannis Haralambous has drawn beautiful glyphs for the Omega +typesetting system . And so +on. Scattered around the internet there are numerous other free +resources for other national scripts, many of them aiming to be a +suitable match for Latin fonts like Times or Helvetica. + + +What do we plan to achieve, and how? + +Our aim is to collect available resources, fill in the missing pieces, +and provide a set of free high-quality scalable (Type 1 and Truetype) +UCS fonts, released under GPL. + +Free UCS scalable fonts will cover the following character sets + +# ISO 8859 parts 1-15 +# CEN MES-3 European Unicode Subset + http://www.evertype.com/standards/iso10646/pdf/cwa13873.pdf +# IBM/Microsoft code pages 437, 850, 852, 1250, 1252 and more +# Microsoft/Adobe Windows Glyph List 4 (WGL4) + http://partners.adobe.com/asn/developer/opentype/appendices/wgl4.html +# KOI8-R and KOI8-RU +# DEC VT100 graphics symbols +# International Phonetic Alphabet +# Arabic, Hebrew, Armenian, Georgian, Ethiopian, Thai and Lao alphabets, + including Arabic presentation forms A/B +# Japanese Katakana and Hiragana +# mathematical symbols, including the whole TeX repertoire of symbols +# APL symbols + etc. + +A free Postscript font editor, George Williams's Pfaedit + will be used for creating new +glyphs. + +Which font shapes should be made? As historical style terms like +Renaissance or Baroque letterforms cannot be applied beyond +Latin/Cyrillic/Greek scripts to any greater extent than Kufi or Nashki +can be applied beyond Arabic script, a smaller subset of styles will +be made: one monospaced and two proportional (one with uniform stroke +and one with modulated) will be made at the start. + +In the beginning, however, we don't believe that Truetype hinting will +be good enough to compete with neither the hand-crafted bitmapped +fonts at small sizes, nor with commercial TrueType fonts. A companion +program for modifying the TrueType font tables, TtfMod, is in the +works, though: . For +applications like xterm, users are referred to the existing UCS bitmap +fonts, . + + +What do the file suffices mean? + +The files with .sfd (Spline Font Database) are in PfaEdit's native +format. Please use these if you plan to modify the font files. PfaEdit +can export these to mostly any existing font file format. + +TrueType fonts for immediate consumption are the files with the .ttf +(TrueType Font) suffix. You can use them directly, e.g. with the X +font server. + +The files with .ps (PostScript) suffix are not font files at all - +they are merely PostScript files with glyph tables, which can be used +for overview, which glyphs are contained in which font file. + +You may have noticed the lacking of PostScript Type 1 (.pfa/.pfb) font +files. Type 1 format does not support large (> 256) encoding vectors, +so they can not be used with ISO 10646 encoding. If your printer +supports it, you can use Type 0 format, though. Please use PfaEdit for +conversion to Type 0. + + +Primoz Peterlin, + +Free UCS scalable fonts: ftp:#biofiz.mf.uni-lj.si/pub/fonts/elbrus/ diff --git a/lib/plugins/rfpdf/lib/fonts/freesans.rb b/lib/plugins/rfpdf/lib/fonts/freesans.rb new file mode 100644 index 000000000..68e40983d --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freesans.rb @@ -0,0 +1,149 @@ +TCPDFFontDescriptor.define('freesans') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='FreeSans'; + font[:desc]={'Ascent'=>1141,'Descent'=>-459,'CapHeight'=>1141,'Flags'=>32,'FontBBox'=>'[-797 -459 1632 1141]','ItalicAngle'=>0,'StemV'=>70,'MissingWidth'=>600} + font[:up]=-151; + font[:ut]=50; + font[:cw]={ + 13=>333, 32=>278, 33=>278, 34=>355, 35=>556, 36=>556, 37=>889, 38=>667, 39=>191, 40=>333, 41=>333, 42=>389, 43=>584, 44=>278, 45=>333, 46=>278, + 47=>278, 48=>556, 49=>556, 50=>556, 51=>556, 52=>556, 53=>556, 54=>556, 55=>556, 56=>556, 57=>556, 58=>278, 59=>278, 60=>584, 61=>584, 62=>584, + 63=>556, 64=>1015, 65=>667, 66=>667, 67=>722, 68=>722, 69=>667, 70=>611, 71=>778, 72=>722, 73=>278, 74=>500, 75=>667, 76=>556, 77=>833, 78=>722, + 79=>778, 80=>667, 81=>778, 82=>722, 83=>667, 84=>611, 85=>722, 86=>667, 87=>944, 88=>667, 89=>667, 90=>611, 91=>278, 92=>278, 93=>278, 94=>469, + 95=>556, 96=>333, 97=>556, 98=>556, 99=>500, 100=>556, 101=>556, 102=>278, 103=>556, 104=>556, 105=>222, 106=>222, 107=>500, 108=>222, 109=>833, 110=>556, + 111=>556, 112=>556, 113=>556, 114=>333, 115=>500, 116=>278, 117=>556, 118=>500, 119=>722, 120=>500, 121=>500, 122=>500, 123=>334, 124=>260, 125=>334, 126=>584, + 8364=>556, 1027=>611, 8218=>222, 402=>556, 8222=>333, 8230=>1000, 8224=>556, 8225=>556, 710=>333, 8240=>1000, 352=>667, 8249=>333, 338=>1000, 1036=>667, 381=>611, 1039=>722, + 8216=>222, 8217=>221, 8220=>333, 8221=>333, 8226=>350, 8211=>556, 8212=>1000, 732=>333, 8482=>1000, 353=>500, 8250=>333, 339=>944, 1116=>500, 382=>500, 376=>667, 160=>278, + 161=>333, 162=>556, 163=>556, 164=>556, 165=>556, 166=>260, 167=>556, 168=>333, 169=>737, 170=>370, 171=>556, 172=>584, 173=>333, 174=>737, 175=>333, 176=>606, + 177=>584, 178=>351, 179=>351, 180=>333, 181=>556, 182=>537, 183=>278, 184=>333, 185=>351, 186=>365, 187=>556, 188=>869, 189=>869, 190=>869, 191=>611, 192=>667, + 193=>667, 194=>667, 195=>667, 196=>667, 197=>667, 198=>1000, 199=>722, 200=>667, 201=>667, 202=>667, 203=>667, 204=>278, 205=>278, 206=>278, 207=>278, 208=>722, + 209=>722, 210=>778, 211=>778, 212=>778, 213=>778, 214=>778, 215=>584, 216=>778, 217=>722, 218=>722, 219=>722, 220=>722, 221=>666, 222=>666, 223=>611, 224=>556, + 225=>556, 226=>556, 227=>556, 228=>556, 229=>556, 230=>889, 231=>500, 232=>556, 233=>556, 234=>556, 235=>556, 236=>278, 237=>278, 238=>278, 239=>278, 240=>556, + 241=>556, 242=>556, 243=>556, 244=>556, 245=>556, 246=>556, 247=>584, 248=>611, 249=>556, 250=>556, 251=>556, 252=>556, 253=>500, 254=>555, 255=>500, 256=>667, + 257=>556, 258=>667, 259=>556, 260=>667, 261=>556, 262=>722, 263=>500, 264=>722, 265=>500, 266=>722, 267=>500, 268=>722, 269=>500, 270=>722, 271=>635, 272=>722, + 273=>556, 274=>667, 275=>556, 276=>667, 277=>556, 278=>667, 279=>556, 280=>667, 281=>556, 282=>667, 283=>556, 284=>778, 285=>556, 286=>778, 287=>556, 288=>778, + 289=>556, 290=>778, 291=>556, 292=>722, 293=>556, 294=>722, 295=>556, 296=>278, 297=>278, 298=>278, 299=>222, 300=>278, 301=>278, 302=>278, 303=>222, 304=>278, + 305=>278, 306=>700, 307=>374, 308=>500, 309=>222, 310=>667, 311=>500, 312=>500, 313=>556, 314=>222, 315=>556, 316=>222, 317=>556, 318=>292, 319=>556, 320=>500, + 321=>556, 322=>222, 323=>722, 324=>556, 325=>722, 326=>556, 327=>722, 328=>556, 329=>556, 330=>722, 331=>556, 332=>778, 333=>556, 334=>778, 335=>556, 336=>778, + 337=>556, 340=>722, 341=>333, 342=>722, 343=>333, 344=>722, 345=>333, 346=>667, 347=>500, 348=>667, 349=>500, 350=>667, 351=>500, 354=>611, 355=>278, 356=>611, + 357=>308, 358=>611, 359=>278, 360=>722, 361=>556, 362=>722, 363=>556, 364=>722, 365=>556, 366=>722, 367=>556, 368=>722, 369=>556, 370=>722, 371=>556, 372=>944, + 373=>722, 374=>667, 375=>500, 377=>611, 378=>500, 379=>611, 380=>500, 383=>278, 384=>556, 386=>667, 387=>556, 388=>667, 389=>556, 390=>722, 391=>722, 392=>500, + 393=>722, 395=>667, 396=>556, 398=>667, 399=>778, 400=>667, 401=>611, 403=>778, 409=>500, 413=>722, 414=>556, 415=>778, 421=>556, 423=>667, 424=>500, 425=>611, + 427=>278, 429=>278, 430=>611, 452=>1311, 453=>1208, 454=>1056, 455=>1056, 456=>778, 457=>444, 458=>1158, 459=>944, 460=>778, 461=>667, 462=>556, 463=>278, 464=>278, + 465=>778, 466=>556, 467=>722, 468=>556, 469=>722, 470=>556, 471=>722, 472=>556, 473=>722, 474=>556, 475=>722, 476=>556, 477=>556, 478=>667, 479=>556, 480=>667, + 481=>556, 482=>1000, 483=>889, 486=>778, 487=>556, 488=>667, 489=>500, 490=>778, 491=>556, 492=>778, 493=>556, 496=>222, 497=>1333, 498=>1222, 499=>1056, 500=>778, + 501=>556, 504=>722, 505=>556, 506=>667, 507=>556, 508=>1000, 509=>889, 510=>778, 511=>611, 512=>667, 513=>556, 514=>667, 515=>556, 516=>667, 517=>556, 518=>667, + 519=>556, 520=>278, 521=>278, 522=>278, 523=>278, 524=>778, 525=>556, 526=>778, 527=>556, 528=>722, 529=>333, 530=>722, 531=>333, 532=>722, 533=>556, 534=>722, + 535=>556, 536=>667, 537=>500, 538=>611, 539=>278, 542=>722, 543=>556, 550=>667, 551=>556, 552=>667, 553=>556, 554=>778, 555=>556, 556=>778, 557=>556, 558=>778, + 559=>556, 560=>778, 561=>556, 562=>667, 563=>500, 592=>556, 593=>556, 594=>556, 595=>556, 596=>500, 598=>556, 599=>556, 600=>556, 601=>556, 603=>500, 604=>500, + 608=>556, 609=>556, 613=>556, 614=>556, 615=>556, 616=>222, 617=>222, 618=>278, 621=>222, 623=>833, 624=>833, 625=>833, 626=>556, 627=>556, 629=>556, 633=>333, + 634=>333, 635=>333, 636=>333, 637=>333, 638=>278, 639=>278, 642=>500, 643=>278, 644=>278, 645=>278, 647=>278, 648=>278, 649=>556, 652=>500, 653=>722, 654=>500, + 656=>500, 668=>500, 670=>500, 672=>556, 711=>333, 714=>333, 715=>333, 728=>333, 729=>333, 730=>333, 731=>333, 733=>333, 768=>0, 769=>0, 770=>0, 771=>0, + 772=>0, 774=>0, 775=>0, 776=>0, 778=>0, 779=>0, 780=>0, 783=>0, 785=>0, 786=>0, 787=>0, 788=>0, 806=>0, 807=>0, 808=>0, 884=>199, + 885=>199, 890=>332, 894=>278, 900=>414, 901=>747, 902=>730, 903=>278, 904=>664, 905=>681, 906=>230, 908=>792, 910=>710, 911=>758, 912=>286, 913=>684, 914=>628, + 915=>582, 916=>684, 917=>650, 918=>628, 919=>683, 920=>750, 921=>236, 922=>684, 923=>684, 924=>800, 925=>654, 926=>630, 927=>750, 928=>721, 929=>638, 931=>628, + 932=>628, 933=>684, 934=>717, 935=>723, 936=>745, 937=>720, 938=>236, 939=>684, 940=>608, 941=>528, 942=>547, 943=>307, 944=>515, 945=>596, 946=>516, 947=>531, + 948=>560, 949=>510, 950=>462, 951=>526, 952=>526, 953=>286, 954=>516, 955=>560, 956=>574, 957=>504, 958=>470, 959=>550, 960=>661, 961=>566, 962=>535, 963=>616, + 964=>532, 965=>515, 966=>741, 967=>572, 968=>662, 969=>740, 970=>286, 971=>515, 972=>553, 973=>518, 974=>740, 1024=>667, 1025=>667, 1026=>766, 1028=>722, 1029=>667, + 1030=>278, 1031=>278, 1032=>500, 1033=>1080, 1034=>1014, 1035=>766, 1037=>722, 1038=>650, 1040=>667, 1041=>667, 1042=>667, 1043=>611, 1044=>812, 1045=>667, 1046=>1023, 1047=>667, + 1048=>728, 1049=>728, 1050=>667, 1051=>673, 1052=>844, 1053=>719, 1054=>778, 1055=>719, 1056=>667, 1057=>722, 1058=>611, 1059=>650, 1060=>936, 1061=>667, 1062=>741, 1063=>648, + 1064=>828, 1065=>850, 1066=>897, 1067=>872, 1068=>667, 1069=>722, 1070=>1032, 1071=>702, 1072=>556, 1073=>556, 1074=>522, 1075=>430, 1076=>602, 1077=>556, 1078=>837, 1079=>500, + 1080=>567, 1081=>567, 1082=>510, 1083=>557, 1084=>618, 1085=>558, 1086=>556, 1087=>557, 1088=>576, 1089=>500, 1090=>496, 1091=>500, 1092=>912, 1093=>500, 1094=>578, 1095=>520, + 1096=>692, 1097=>712, 1098=>734, 1099=>690, 1100=>552, 1101=>500, 1102=>758, 1103=>543, 1104=>556, 1105=>556, 1106=>568, 1107=>430, 1108=>500, 1109=>500, 1110=>222, 1111=>278, + 1112=>222, 1113=>840, 1114=>850, 1115=>568, 1117=>556, 1118=>500, 1119=>556, 1164=>667, 1165=>552, 1166=>667, 1167=>556, 1168=>611, 1169=>430, 1170=>611, 1171=>430, 1172=>611, + 1173=>430, 1174=>1023, 1175=>837, 1176=>667, 1177=>500, 1178=>667, 1179=>500, 1180=>667, 1181=>500, 1182=>667, 1183=>500, 1184=>667, 1185=>500, 1186=>722, 1187=>556, 1188=>1060, + 1189=>764, 1190=>722, 1191=>556, 1192=>722, 1193=>500, 1194=>722, 1195=>500, 1196=>611, 1197=>496, 1198=>667, 1199=>500, 1200=>667, 1201=>500, 1202=>667, 1203=>500, 1204=>774, + 1205=>608, 1206=>642, 1207=>508, 1208=>642, 1209=>508, 1210=>642, 1211=>508, 1212=>778, 1213=>556, 1214=>688, 1215=>556, 1216=>278, 1217=>1023, 1218=>837, 1219=>667, 1220=>500, + 1223=>722, 1224=>556, 1227=>642, 1228=>508, 1232=>667, 1233=>556, 1234=>667, 1235=>556, 1236=>1000, 1237=>889, 1238=>667, 1239=>556, 1240=>778, 1241=>556, 1242=>778, 1243=>556, + 1244=>1023, 1245=>837, 1246=>667, 1247=>500, 1248=>667, 1249=>500, 1250=>728, 1251=>567, 1252=>728, 1253=>567, 1254=>778, 1255=>556, 1256=>778, 1257=>556, 1258=>778, 1259=>556, + 1260=>722, 1261=>500, 1262=>650, 1263=>500, 1264=>650, 1265=>500, 1266=>650, 1267=>500, 1268=>648, 1269=>520, 1272=>872, 1273=>690, 1329=>722, 1330=>705, 1331=>774, 1332=>754, + 1333=>722, 1334=>751, 1335=>485, 1336=>722, 1337=>782, 1338=>655, 1339=>699, 1340=>417, 1341=>853, 1342=>791, 1343=>711, 1344=>588, 1345=>663, 1346=>665, 1347=>665, 1348=>756, + 1349=>623, 1350=>773, 1351=>603, 1352=>722, 1353=>648, 1354=>722, 1355=>751, 1356=>750, 1357=>722, 1358=>748, 1359=>667, 1360=>699, 1361=>623, 1362=>417, 1363=>785, 1364=>638, + 1365=>778, 1366=>716, 1370=>222, 1371=>133, 1372=>325, 1373=>333, 1374=>344, 1377=>833, 1378=>556, 1379=>572, 1380=>581, 1381=>550, 1382=>588, 1383=>448, 1384=>556, 1385=>568, + 1386=>582, 1387=>545, 1388=>301, 1389=>799, 1390=>556, 1391=>554, 1392=>533, 1393=>548, 1394=>552, 1395=>552, 1396=>544, 1397=>222, 1398=>544, 1399=>456, 1400=>556, 1401=>390, + 1402=>833, 1403=>509, 1404=>547, 1405=>533, 1406=>610, 1407=>887, 1408=>556, 1409=>545, 1410=>352, 1411=>853, 1412=>588, 1413=>579, 1414=>690, 1415=>545, 1417=>278, 1418=>367, + 1456=>70, 1457=>335, 1458=>329, 1459=>329, 1460=>70, 1461=>200, 1462=>200, 1463=>188, 1464=>188, 1465=>70, 1467=>329, 1468=>70, 1469=>70, 1470=>488, 1471=>200, 1472=>212, + 1473=>0, 1474=>0, 1475=>278, 1476=>70, 1488=>640, 1489=>591, 1490=>466, 1491=>598, 1492=>622, 1493=>212, 1494=>351, 1495=>623, 1496=>608, 1497=>200, 1498=>526, 1499=>550, + 1500=>600, 1501=>623, 1502=>621, 1503=>212, 1504=>378, 1505=>607, 1506=>587, 1507=>575, 1508=>568, 1509=>540, 1510=>590, 1511=>606, 1512=>547, 1513=>776, 1514=>687, 1792=>600, + 1793=>201, 1794=>201, 1795=>201, 1796=>201, 1797=>500, 1798=>500, 1799=>500, 1800=>370, 1801=>370, 1802=>574, 1803=>574, 1804=>645, 1805=>574, 1808=>452, 1809=>452, 1810=>574, + 1811=>645, 1812=>645, 1813=>509, 1814=>509, 1815=>682, 1816=>585, 1817=>404, 1818=>627, 1819=>718, 1820=>718, 1821=>484, 1822=>682, 1823=>600, 1824=>660, 1825=>682, 1826=>538, + 1827=>718, 1828=>718, 1829=>718, 1830=>574, 1831=>574, 1832=>638, 1833=>585, 1834=>509, 1835=>682, 1836=>682, 1840=>1, 1841=>1, 1842=>1, 1843=>1, 1844=>1, 1845=>1, + 1846=>1, 1847=>1, 1848=>1, 1849=>1, 1850=>1, 1851=>1, 1852=>1, 1853=>1, 1854=>1, 1855=>1, 1856=>1, 1857=>1, 1858=>1, 1859=>1, 1860=>1, 1861=>1, + 1862=>1, 1863=>1, 1864=>1, 1865=>1, 1866=>1, 2305=>6, 2306=>6, 2309=>644, 2310=>816, 2311=>392, 2312=>392, 2313=>459, 2314=>661, 2315=>641, 2317=>423, 2320=>423, + 2321=>816, 2323=>816, 2324=>816, 2325=>393, 2326=>622, 2327=>424, 2328=>472, 2329=>508, 2330=>517, 2331=>583, 2332=>549, 2333=>503, 2334=>538, 2335=>444, 2336=>480, 2337=>519, + 2338=>479, 2339=>504, 2340=>439, 2341=>542, 2342=>427, 2343=>520, 2344=>415, 2345=>415, 2346=>401, 2347=>401, 2348=>442, 2349=>520, 2350=>463, 2351=>451, 2352=>319, 2353=>319, + 2354=>549, 2355=>641, 2357=>442, 2358=>589, 2359=>398, 2360=>506, 2361=>430, 2364=>6, 2365=>438, 2366=>172, 2367=>172, 2368=>172, 2369=>6, 2370=>6, 2371=>6, 2373=>6, + 2375=>6, 2376=>6, 2377=>172, 2379=>172, 2380=>172, 2381=>6, 2384=>898, 2385=>6, 2406=>584, 2407=>584, 2408=>584, 2409=>584, 2410=>584, 2411=>584, 2412=>584, 2413=>584, + 2414=>584, 2415=>584, 2416=>898, 2433=>300, 2434=>400, 2435=>300, 2437=>640, 2438=>780, 2439=>520, 2440=>520, 2441=>530, 2442=>550, 2443=>620, 2444=>420, 2447=>480, 2448=>620, + 2451=>620, 2452=>720, 2453=>652, 2454=>500, 2455=>490, 2456=>466, 2457=>540, 2458=>490, 2459=>540, 2460=>630, 2461=>590, 2462=>680, 2463=>510, 2464=>490, 2465=>520, 2466=>520, + 2467=>470, 2468=>540, 2469=>490, 2470=>470, 2471=>490, 2472=>452, 2474=>560, 2475=>650, 2476=>480, 2477=>588, 2478=>480, 2479=>470, 2480=>480, 2482=>472, 2486=>512, 2487=>470, + 2488=>470, 2489=>520, 2492=>160, 2494=>180, 2495=>180, 2496=>180, 2497=>320, 2498=>329, 2499=>195, 2500=>260, 2503=>340, 2504=>340, 2507=>740, 2508=>740, 2509=>400, 2519=>180, + 2524=>540, 2525=>520, 2527=>470, 2528=>612, 2529=>420, 2530=>234, 2531=>360, 2534=>460, 2535=>420, 2536=>520, 2537=>540, 2538=>400, 2539=>400, 2540=>560, 2541=>390, 2542=>480, + 2543=>420, 2544=>480, 2545=>470, 2546=>400, 2547=>470, 2548=>400, 2549=>400, 2550=>400, 2551=>120, 2552=>440, 2553=>420, 2554=>420, 2565=>744, 2566=>914, 2567=>690, 2568=>670, + 2569=>596, 2570=>596, 2575=>498, 2576=>744, 2579=>596, 2580=>744, 2581=>550, 2582=>534, 2583=>618, 2584=>690, 2585=>546, 2586=>518, 2587=>592, 2588=>492, 2589=>574, 2590=>514, + 2591=>526, 2592=>556, 2593=>524, 2594=>528, 2595=>574, 2596=>484, 2597=>534, 2598=>504, 2599=>534, 2600=>538, 2602=>534, 2603=>506, 2604=>562, 2605=>516, 2606=>546, 2607=>670, + 2608=>538, 2610=>726, 2611=>726, 2613=>514, 2614=>546, 2616=>546, 2617=>517, 2620=>286, 2622=>172, 2623=>190, 2624=>190, 2625=>1, 2626=>1, 2631=>1, 2632=>1, 2635=>1, + 2636=>1, 2637=>1, 2649=>534, 2650=>618, 2651=>492, 2652=>484, 2654=>506, 2662=>616, 2663=>480, 2664=>560, 2665=>480, 2666=>468, 2667=>492, 2668=>514, 2669=>538, 2670=>572, + 2671=>560, 2672=>1, 2674=>498, 2675=>596, 2676=>900, 2689=>33, 2690=>33, 2693=>767, 2694=>961, 2695=>500, 2696=>495, 2697=>528, 2698=>702, 2699=>885, 2709=>501, 2710=>612, + 2711=>619, 2712=>569, 2713=>532, 2714=>358, 2715=>620, 2716=>606, 2717=>602, 2718=>631, 2719=>495, 2720=>528, 2721=>531, 2722=>511, 2723=>614, 2724=>294, 2725=>344, 2726=>425, + 2727=>345, 2728=>611, 2730=>512, 2731=>578, 2732=>428, 2733=>423, 2734=>231, 2735=>582, 2736=>344, 2738=>558, 2739=>670, 2741=>537, 2742=>592, 2743=>568, 2744=>600, 2745=>544, + 2749=>531, 2750=>232, 2751=>232, 2752=>232, 2753=>33, 2754=>33, 2755=>33, 2759=>33, 2760=>33, 2763=>232, 2764=>232, 2768=>903, 2790=>479, 2791=>416, 2792=>465, 2793=>469, + 2794=>498, 2795=>463, 2796=>451, 2797=>510, 2798=>455, 2799=>488, 2818=>131, 2819=>302, 2821=>560, 2822=>644, 2823=>632, 2825=>630, 2827=>553, 2831=>604, 2835=>520, 2837=>572, + 2838=>570, 2839=>580, 2840=>565, 2842=>580, 2844=>564, 2845=>575, 2847=>565, 2848=>565, 2849=>524, 2858=>572, 2859=>700, 2863=>655, 2864=>620, 2866=>652, 2867=>560, 2870=>565, + 2871=>565, 2872=>545, 2873=>524, 2878=>128, 2879=>1, 2880=>190, 2881=>1, 2882=>1, 2883=>1, 2887=>396, 2912=>563, 2918=>508, 2919=>424, 2920=>440, 2921=>600, 2922=>600, + 2923=>600, 2924=>600, 2925=>600, 2926=>511, 2927=>483, 2946=>479, 2947=>893, 2949=>1018, 2950=>1170, 2951=>916, 2952=>676, 2953=>836, 2954=>1225, 2958=>744, 2959=>744, 2960=>848, + 2962=>813, 2963=>813, 2964=>813, 2965=>688, 2969=>744, 2970=>676, 2972=>848, 2974=>984, 2975=>777, 2979=>1338, 2980=>664, 2984=>561, 2985=>1029, 2986=>607, 2990=>697, 2991=>697, + 2992=>434, 2993=>617, 2994=>869, 2995=>859, 2996=>697, 2997=>869, 2999=>1145, 3000=>1064, 3001=>1316, 3006=>424, 3007=>125, 3008=>596, 3009=>539, 3014=>596, 3015=>650, 3016=>973, + 3018=>1286, 3019=>1286, 3020=>1706, 3021=>333, 3031=>859, 3034=>778, 3035=>881, 3036=>876, 3037=>648, 3041=>744, 3203=>342, 3205=>620, 3206=>591, 3207=>600, 3208=>776, 3209=>1138, + 3210=>1464, 3214=>574, 3215=>570, 3216=>580, 3218=>589, 3219=>597, 3220=>625, 3221=>256, 3222=>565, 3223=>326, 3224=>604, 3225=>651, 3226=>408, 3228=>611, 3230=>843, 3231=>610, + 3232=>258, 3233=>317, 3234=>328, 3235=>803, 3236=>317, 3237=>328, 3238=>352, 3239=>352, 3240=>317, 3248=>248, 3249=>621, 3250=>620, 3251=>620, 3302=>649, 3303=>550, 3304=>573, + 3305=>567, 3306=>562, 3307=>557, 3308=>562, 3309=>567, 3310=>557, 3311=>557, 3458=>468, 3459=>318, 3461=>660, 3465=>778, 3466=>807, 3467=>830, 3473=>838, 3476=>860, 3481=>1000, + 3482=>973, 3483=>860, 3484=>997, 3486=>740, 3488=>838, 3489=>886, 3490=>886, 3492=>1295, 3493=>1295, 3495=>838, 3496=>860, 3497=>860, 3498=>860, 3499=>1403, 3501=>973, 3502=>838, + 3503=>660, 3504=>860, 3505=>973, 3507=>660, 3508=>886, 3509=>838, 3510=>860, 3511=>973, 3512=>838, 3513=>860, 3514=>886, 3515=>807, 3517=>830, 3520=>838, 3521=>973, 3522=>886, + 3523=>886, 3524=>973, 3525=>830, 3526=>973, 3530=>0, 3535=>432, 3536=>380, 3537=>420, 3538=>0, 3539=>0, 3540=>0, 3542=>0, 3544=>501, 3545=>652, 3551=>648, 7936=>596, + 7937=>596, 7938=>596, 7939=>596, 7940=>596, 7941=>596, 7942=>596, 7943=>596, 7944=>684, 7945=>684, 7946=>684, 7947=>684, 7948=>684, 7949=>684, 7950=>684, 7951=>684, 7952=>510, + 7953=>510, 7954=>510, 7955=>510, 7956=>510, 7957=>510, 7960=>650, 7961=>650, 7962=>650, 7963=>650, 7964=>650, 7965=>650, 7968=>526, 7969=>526, 7970=>526, 7971=>526, 7972=>526, + 7973=>526, 7974=>526, 7975=>526, 7976=>683, 7977=>683, 7978=>683, 7979=>683, 7980=>683, 7981=>683, 7982=>683, 7983=>683, 7984=>286, 7985=>286, 7986=>286, 7987=>286, 7988=>286, + 7989=>286, 7990=>286, 7991=>286, 7992=>236, 7993=>236, 7994=>236, 7995=>236, 7996=>236, 7997=>236, 7998=>236, 7999=>236, 8000=>550, 8001=>550, 8002=>550, 8003=>550, 8004=>550, + 8005=>550, 8008=>750, 8009=>750, 8010=>750, 8011=>750, 8012=>750, 8013=>750, 8016=>515, 8017=>515, 8018=>515, 8019=>515, 8020=>515, 8021=>515, 8022=>515, 8023=>515, 8025=>684, + 8027=>684, 8029=>684, 8031=>684, 8032=>740, 8033=>740, 8034=>740, 8035=>740, 8036=>740, 8037=>740, 8038=>740, 8039=>740, 8040=>720, 8041=>720, 8042=>720, 8043=>720, 8044=>720, + 8045=>720, 8046=>720, 8047=>720, 8048=>596, 8049=>596, 8050=>510, 8051=>510, 8052=>526, 8053=>526, 8054=>286, 8055=>286, 8056=>550, 8057=>550, 8058=>515, 8059=>515, 8060=>740, + 8061=>740, 8064=>596, 8065=>596, 8066=>596, 8067=>596, 8068=>596, 8069=>596, 8070=>596, 8071=>596, 8072=>882, 8073=>882, 8074=>882, 8075=>882, 8076=>882, 8077=>882, 8078=>882, + 8079=>882, 8080=>526, 8081=>526, 8082=>526, 8083=>526, 8084=>526, 8085=>526, 8086=>526, 8087=>526, 8088=>857, 8089=>857, 8090=>857, 8091=>857, 8092=>857, 8093=>857, 8094=>857, + 8095=>857, 8096=>740, 8097=>740, 8098=>740, 8099=>740, 8100=>740, 8101=>740, 8102=>740, 8103=>740, 8104=>945, 8105=>945, 8106=>945, 8107=>945, 8108=>945, 8109=>945, 8110=>945, + 8111=>945, 8112=>596, 8113=>596, 8114=>596, 8115=>596, 8116=>596, 8118=>596, 8119=>596, 8120=>684, 8121=>684, 8122=>684, 8123=>684, 8124=>882, 8125=>278, 8126=>201, 8127=>333, + 8128=>278, 8129=>333, 8130=>526, 8131=>526, 8132=>536, 8134=>526, 8135=>526, 8136=>650, 8137=>650, 8138=>683, 8139=>683, 8140=>857, 8141=>582, 8142=>582, 8143=>333, 8144=>286, + 8145=>286, 8146=>286, 8147=>286, 8150=>286, 8151=>312, 8152=>236, 8153=>236, 8154=>236, 8155=>236, 8157=>582, 8158=>582, 8159=>333, 8160=>515, 8161=>515, 8162=>515, 8163=>515, + 8164=>566, 8165=>566, 8166=>515, 8167=>515, 8168=>684, 8169=>684, 8170=>684, 8171=>684, 8172=>638, 8173=>333, 8174=>393, 8175=>333, 8178=>740, 8179=>740, 8180=>740, 8182=>740, + 8183=>740, 8184=>750, 8185=>750, 8186=>720, 8187=>720, 8188=>939, 8189=>333, 8190=>333, 8208=>333, 8219=>221, 8223=>333, 8227=>350, 8241=>1360, 8242=>278, 8243=>469, 8244=>680, + 8245=>278, 8246=>469, 8247=>680, 8251=>622, 8252=>556, 8253=>556, 8260=>167, 8263=>1112, 8264=>834, 8265=>834, 8267=>537, 8304=>351, 8305=>351, 8308=>351, 8309=>351, 8310=>351, + 8311=>351, 8312=>351, 8313=>351, 8320=>351, 8321=>351, 8322=>351, 8323=>351, 8324=>351, 8325=>353, 8326=>351, 8327=>351, 8328=>351, 8329=>351, 8359=>1445, 8360=>1222, 8362=>869, + 8459=>969, 8460=>615, 8464=>809, 8465=>519, 8466=>874, 8470=>1008, 8475=>850, 8476=>644, 8486=>720, 8487=>720, 8488=>512, 8490=>667, 8491=>667, 8492=>908, 8493=>623, 8496=>562, + 8497=>611, 8498=>611, 8499=>1080, 8531=>869, 8532=>869, 8533=>869, 8534=>869, 8535=>869, 8536=>869, 8537=>869, 8538=>869, 8539=>869, 8540=>869, 8541=>869, 8542=>869, 8543=>869, + 8544=>278, 8545=>556, 8546=>834, 8547=>945, 8548=>667, 8549=>945, 8550=>1223, 8551=>1501, 8552=>945, 8553=>667, 8554=>945, 8555=>1223, 8556=>556, 8557=>722, 8558=>722, 8559=>833, + 8560=>222, 8561=>444, 8562=>666, 8563=>722, 8564=>500, 8565=>722, 8566=>944, 8567=>1166, 8568=>722, 8569=>500, 8570=>722, 8571=>944, 8572=>222, 8573=>500, 8574=>556, 8575=>833, + 8592=>987, 8593=>603, 8594=>987, 8595=>603, 8596=>1042, 8597=>1042, 8629=>658, 8656=>987, 8657=>603, 8658=>987, 8659=>603, 8660=>1042, 8704=>667, 8706=>556, 8707=>667, 8709=>556, + 8710=>711, 8711=>711, 8712=>713, 8713=>713, 8719=>823, 8720=>823, 8721=>804, 8722=>584, 8723=>584, 8727=>500, 8730=>542, 8733=>713, 8734=>713, 8736=>768, 8743=>603, 8744=>603, + 8745=>768, 8746=>768, 8747=>556, 8748=>796, 8749=>956, 8750=>556, 8756=>863, 8764=>549, 8766=>584, 8769=>584, 8770=>584, 8771=>584, 8777=>636, 8800=>548, 8804=>584, 8805=>584, + 8853=>768, 8854=>768, 8855=>768, 8869=>658, 8960=>823, 9674=>489, 9834=>555, 12289=>1000, 12290=>1000, 12291=>1000, 12293=>1000, 12295=>1000, 12296=>1000, 12297=>1000, 12298=>1000, 12299=>1000, + 12300=>1000, 12301=>1000, 12302=>1000, 12303=>1000, 12304=>1000, 12305=>1000, 12308=>1000, 12309=>1000, 12353=>1000, 12354=>1000, 12355=>1000, 12356=>1000, 12357=>1000, 12358=>1000, 12359=>1000, 12360=>1000, + 12361=>1000, 12362=>1000, 12363=>1000, 12364=>1000, 12365=>1000, 12366=>1000, 12367=>1000, 12368=>1000, 12369=>1000, 12370=>1000, 12371=>1000, 12372=>1000, 12373=>1000, 12374=>1000, 12375=>1000, 12376=>1000, + 12377=>1000, 12378=>1000, 12379=>1000, 12380=>1000, 12381=>1000, 12382=>1000, 12383=>1000, 12384=>1000, 12385=>1000, 12386=>1000, 12387=>1000, 12388=>1000, 12389=>1000, 12390=>1000, 12391=>1000, 12392=>1000, + 12393=>1000, 12394=>1000, 12395=>1000, 12396=>1000, 12397=>1000, 12398=>1000, 12399=>1000, 12400=>1000, 12401=>1000, 12402=>1000, 12403=>1000, 12404=>1000, 12405=>1000, 12406=>1000, 12407=>1000, 12408=>1000, + 12409=>1000, 12410=>1000, 12411=>1000, 12412=>1000, 12413=>1000, 12414=>1000, 12415=>1000, 12416=>1000, 12417=>1000, 12418=>1000, 12419=>1000, 12420=>1000, 12421=>1000, 12422=>1000, 12423=>1000, 12424=>1000, + 12425=>1000, 12426=>1000, 12427=>1000, 12428=>1000, 12429=>1000, 12430=>1000, 12431=>1000, 12432=>1000, 12433=>1000, 12434=>1000, 12435=>1000, 12441=>1000, 12443=>1000, 12449=>1000, 12450=>1000, 12451=>1000, + 12452=>1000, 12453=>1000, 12454=>1000, 12455=>1000, 12456=>1000, 12457=>1000, 12458=>1000, 12459=>1000, 12460=>1000, 12461=>1000, 12462=>1000, 12463=>1000, 12464=>1000, 12465=>1000, 12466=>1000, 12467=>1000, + 12468=>1000, 12469=>1000, 12470=>1000, 12471=>1000, 12472=>1000, 12473=>1000, 12474=>1000, 12475=>1000, 12476=>1000, 12477=>1000, 12478=>1000, 12479=>1000, 12480=>1000, 12481=>1000, 12482=>1000, 12483=>1000, + 12484=>1000, 12485=>1000, 12486=>1000, 12487=>1000, 12488=>1000, 12489=>1000, 12490=>1000, 12491=>1000, 12492=>1000, 12493=>1000, 12494=>1000, 12495=>1000, 12496=>1000, 12497=>1000, 12498=>1000, 12499=>1000, + 12500=>1000, 12501=>1000, 12502=>1000, 12503=>1000, 12504=>1000, 12505=>1000, 12506=>1000, 12507=>1000, 12508=>1000, 12509=>1000, 12510=>1000, 12511=>1000, 12512=>1000, 12513=>1000, 12514=>1000, 12515=>1000, + 12516=>1000, 12517=>1000, 12518=>1000, 12519=>1000, 12520=>1000, 12521=>1000, 12522=>1000, 12523=>1000, 12524=>1000, 12525=>1000, 12526=>1000, 12527=>1000, 12528=>1000, 12529=>1000, 12530=>1000, 12531=>1000, + 12532=>1000, 12533=>1000, 12534=>1000, 12535=>1000, 12536=>1000, 12537=>1000, 12538=>1000, 12539=>278, 12540=>1000, 12541=>1000, 12542=>1000, 63033=>556, 63034=>556, 63035=>556, 63036=>556, 63037=>556, + 63038=>556, 63039=>556, 63040=>556, 63041=>556, 63166=>222, 63171=>333, 63196=>556, 64256=>556, 64257=>500, 64258=>500, 64259=>778, 64260=>778, 64261=>556, 64262=>778, 64285=>200, 64286=>305, + 64287=>400, 64288=>587, 64289=>890, 64290=>848, 64291=>872, 64292=>800, 64293=>850, 64294=>873, 64295=>797, 64296=>937, 64297=>584, 64298=>776, 64299=>776, 64300=>776, 64301=>776, 64302=>640, + 64303=>640, 64304=>640, 64305=>591, 64306=>466, 64307=>598, 64308=>622, 64309=>262, 64310=>351, 64312=>608, 64313=>270, 64314=>526, 64315=>550, 64316=>600, 64318=>621, 64320=>378, 64321=>607, + 64323=>575, 64324=>568, 64326=>590, 64327=>606, 64328=>547, 64329=>776, 64330=>687, 64331=>212, 64332=>591, 64333=>550, 64334=>568, 64335=>640, 65533=>788} + font[:enc]=''; + font[:diff]=''; + font[:file]='FreeSans.z'; + font[:ctg]='FreeSans.ctg.z'; + font[:originalsize]=264072; +end diff --git a/lib/plugins/rfpdf/lib/fonts/freesansb.rb b/lib/plugins/rfpdf/lib/fonts/freesansb.rb new file mode 100644 index 000000000..f6e985423 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freesansb.rb @@ -0,0 +1,79 @@ +TCPDFFontDescriptor.define('freesansb') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='FreeSansBold'; + font[:desc]={'Ascent'=>1159,'Descent'=>-355,'CapHeight'=>1159,'Flags'=>32,'FontBBox'=>'[-459 -355 1300 1159]','ItalicAngle'=>0,'StemV'=>120,'MissingWidth'=>600}; + font[:up]=-155; + font[:ut]=69; + font[:cw]={ + 13=>333, 32=>278, 33=>333, 34=>474, 35=>556, 36=>556, 37=>889, 38=>722, 39=>238, 40=>333, 41=>333, 42=>389, 43=>584, 44=>278, 45=>333, 46=>278, + 47=>278, 48=>556, 49=>556, 50=>556, 51=>556, 52=>556, 53=>556, 54=>556, 55=>556, 56=>556, 57=>556, 58=>333, 59=>333, 60=>584, 61=>584, 62=>584, + 63=>611, 64=>975, 65=>722, 66=>722, 67=>722, 68=>722, 69=>667, 70=>611, 71=>778, 72=>722, 73=>278, 74=>556, 75=>722, 76=>611, 77=>833, 78=>722, + 79=>778, 80=>667, 81=>778, 82=>722, 83=>667, 84=>611, 85=>722, 86=>667, 87=>944, 88=>667, 89=>667, 90=>611, 91=>333, 92=>278, 93=>333, 94=>584, + 95=>556, 96=>333, 97=>556, 98=>611, 99=>556, 100=>611, 101=>556, 102=>333, 103=>611, 104=>611, 105=>278, 106=>278, 107=>556, 108=>278, 109=>889, 110=>611, + 111=>611, 112=>611, 113=>611, 114=>389, 115=>556, 116=>333, 117=>611, 118=>556, 119=>778, 120=>556, 121=>556, 122=>500, 123=>389, 124=>280, 125=>389, 126=>584, + 8364=>556, 1027=>611, 8218=>278, 402=>556, 8222=>500, 8230=>1000, 8224=>556, 8225=>556, 710=>333, 8240=>1000, 352=>667, 8249=>333, 338=>1000, 1036=>722, 381=>611, 1039=>722, + 8216=>278, 8217=>278, 8220=>500, 8221=>500, 8226=>350, 8211=>556, 8212=>1000, 732=>333, 8482=>1000, 353=>556, 8250=>333, 339=>944, 1116=>573, 382=>500, 376=>667, 161=>333, + 162=>556, 163=>556, 164=>556, 165=>556, 166=>280, 167=>556, 168=>333, 169=>737, 170=>370, 171=>556, 172=>584, 174=>737, 175=>333, 176=>606, 177=>584, 178=>351, + 179=>351, 180=>333, 181=>611, 182=>556, 183=>278, 184=>333, 185=>351, 186=>365, 187=>556, 188=>869, 189=>869, 190=>869, 191=>611, 192=>722, 193=>722, 194=>722, + 195=>722, 196=>722, 197=>722, 198=>1000, 199=>722, 200=>667, 201=>667, 202=>667, 203=>667, 204=>278, 205=>278, 206=>278, 207=>278, 208=>722, 209=>722, 210=>778, + 211=>778, 212=>778, 213=>778, 214=>778, 215=>584, 216=>778, 217=>722, 218=>722, 219=>722, 220=>722, 221=>667, 222=>667, 223=>611, 224=>556, 225=>556, 226=>556, + 227=>556, 228=>556, 229=>556, 230=>889, 231=>556, 232=>556, 233=>556, 234=>556, 235=>556, 236=>278, 237=>278, 238=>278, 239=>278, 240=>611, 241=>611, 242=>611, + 243=>611, 244=>611, 245=>611, 246=>611, 247=>584, 248=>611, 249=>611, 250=>611, 251=>611, 252=>611, 253=>556, 254=>611, 255=>556, 256=>722, 257=>556, 258=>722, + 259=>556, 260=>722, 261=>556, 262=>722, 263=>556, 264=>722, 265=>556, 266=>722, 267=>556, 268=>722, 269=>556, 270=>722, 271=>611, 272=>722, 273=>611, 274=>667, + 275=>556, 276=>667, 277=>556, 278=>667, 279=>556, 280=>667, 281=>556, 282=>667, 283=>556, 284=>778, 285=>611, 286=>778, 287=>611, 288=>778, 289=>611, 290=>778, + 291=>611, 292=>722, 293=>611, 294=>722, 295=>611, 296=>278, 297=>278, 298=>278, 299=>278, 300=>278, 301=>278, 302=>278, 303=>278, 304=>278, 305=>278, 306=>808, + 307=>492, 308=>556, 309=>278, 310=>722, 311=>556, 312=>573, 313=>611, 314=>278, 315=>611, 316=>278, 317=>611, 318=>278, 319=>611, 320=>556, 321=>611, 322=>278, + 323=>722, 324=>611, 325=>722, 326=>611, 327=>722, 328=>611, 329=>611, 330=>722, 331=>611, 332=>778, 333=>611, 334=>778, 335=>611, 336=>778, 337=>611, 340=>722, + 341=>389, 342=>722, 343=>389, 344=>722, 345=>389, 346=>667, 347=>556, 348=>667, 349=>556, 350=>667, 351=>556, 354=>611, 355=>333, 356=>611, 357=>333, 358=>611, + 359=>333, 360=>722, 361=>611, 362=>722, 363=>611, 364=>722, 365=>611, 366=>722, 367=>611, 368=>722, 369=>611, 370=>722, 371=>611, 372=>944, 373=>778, 374=>667, + 375=>556, 377=>611, 378=>500, 379=>611, 380=>500, 383=>333, 452=>1333, 453=>1222, 454=>1111, 455=>1167, 456=>889, 457=>556, 458=>1278, 459=>1000, 460=>889, 461=>722, + 462=>556, 463=>278, 464=>278, 465=>778, 466=>611, 467=>722, 468=>611, 469=>722, 470=>611, 471=>722, 472=>611, 473=>722, 474=>611, 475=>722, 476=>611, 478=>722, + 479=>556, 482=>1000, 483=>889, 486=>778, 487=>611, 488=>722, 489=>556, 490=>778, 491=>611, 492=>778, 493=>611, 497=>1333, 498=>1222, 499=>1111, 504=>722, 505=>611, + 506=>722, 507=>556, 508=>1000, 509=>889, 510=>778, 511=>611, 514=>722, 515=>556, 518=>667, 519=>556, 522=>278, 523=>278, 526=>778, 527=>611, 530=>722, 531=>389, + 534=>722, 535=>611, 536=>667, 537=>556, 538=>611, 539=>333, 711=>333, 728=>333, 729=>333, 730=>333, 731=>333, 733=>333, 884=>379, 885=>379, 890=>332, 894=>333, + 900=>325, 901=>658, 902=>761, 903=>474, 904=>706, 905=>733, 906=>285, 908=>785, 910=>823, 911=>819, 913=>722, 914=>722, 915=>642, 916=>726, 917=>667, 918=>611, + 919=>722, 920=>810, 921=>278, 922=>722, 923=>744, 924=>860, 925=>714, 926=>690, 927=>822, 928=>781, 929=>698, 931=>688, 932=>688, 933=>804, 934=>777, 935=>783, + 936=>805, 937=>780, 938=>278, 939=>804, 940=>660, 941=>559, 942=>560, 943=>356, 944=>575, 945=>656, 946=>576, 947=>591, 948=>620, 949=>570, 950=>522, 951=>586, + 952=>586, 953=>346, 954=>576, 955=>620, 956=>667, 957=>564, 958=>530, 959=>610, 960=>721, 961=>626, 962=>595, 963=>676, 964=>592, 965=>575, 966=>801, 967=>632, + 968=>722, 969=>800, 970=>346, 971=>575, 972=>599, 973=>567, 974=>1125, 1024=>667, 1025=>709, 1026=>790, 1028=>722, 1029=>667, 1030=>278, 1031=>278, 1032=>556, 1033=>1110, + 1034=>1113, 1035=>790, 1037=>726, 1038=>718, 1040=>722, 1041=>722, 1042=>722, 1043=>611, 1044=>900, 1045=>709, 1046=>1093, 1047=>672, 1048=>757, 1049=>757, 1050=>750, 1051=>729, + 1052=>874, 1053=>753, 1054=>778, 1055=>753, 1056=>671, 1057=>722, 1058=>611, 1059=>718, 1060=>892, 1061=>667, 1062=>816, 1063=>685, 1064=>1057, 1065=>1183, 1066=>928, 1067=>949, + 1068=>687, 1069=>722, 1070=>1109, 1071=>698, 1072=>556, 1073=>606, 1074=>572, 1075=>454, 1076=>685, 1077=>556, 1078=>809, 1079=>546, 1080=>615, 1081=>615, 1082=>573, 1083=>577, + 1084=>666, 1085=>603, 1086=>611, 1087=>603, 1088=>611, 1089=>556, 1090=>454, 1091=>556, 1092=>957, 1093=>556, 1094=>652, 1095=>578, 1096=>886, 1097=>968, 1098=>693, 1099=>811, + 1100=>562, 1101=>564, 1102=>908, 1103=>596, 1104=>556, 1105=>556, 1106=>606, 1107=>454, 1108=>556, 1109=>556, 1110=>278, 1111=>278, 1112=>278, 1113=>900, 1114=>611, 1115=>606, + 1117=>608, 1118=>556, 1119=>608, 1164=>687, 1165=>562, 1166=>667, 1167=>611, 1168=>611, 1169=>454, 1170=>611, 1171=>454, 1172=>611, 1173=>454, 1174=>1093, 1175=>809, 1176=>672, + 1177=>546, 1178=>722, 1179=>573, 1180=>722, 1181=>573, 1182=>722, 1183=>573, 1184=>722, 1185=>573, 1186=>722, 1187=>608, 1188=>722, 1189=>608, 1190=>722, 1191=>608, 1192=>722, + 1193=>556, 1194=>722, 1195=>556, 1196=>611, 1197=>454, 1198=>667, 1199=>556, 1200=>667, 1201=>556, 1202=>667, 1203=>556, 1204=>814, 1205=>685, 1206=>675, 1207=>580, 1208=>675, + 1209=>580, 1210=>675, 1211=>580, 1212=>722, 1213=>556, 1214=>722, 1215=>556, 1216=>278, 1217=>1093, 1218=>809, 1219=>722, 1220=>573, 1223=>722, 1224=>608, 1227=>675, 1228=>580, + 1232=>722, 1233=>556, 1234=>722, 1235=>556, 1236=>1000, 1237=>889, 1238=>709, 1239=>556, 1240=>722, 1241=>556, 1242=>722, 1243=>556, 1244=>1093, 1245=>809, 1246=>672, 1247=>546, + 1248=>672, 1249=>546, 1250=>757, 1251=>615, 1252=>757, 1253=>615, 1254=>778, 1255=>611, 1256=>778, 1257=>611, 1258=>778, 1259=>611, 1260=>722, 1261=>564, 1262=>718, 1263=>556, + 1264=>718, 1265=>556, 1266=>718, 1267=>556, 1268=>685, 1269=>578, 1272=>949, 1273=>811, 1456=>82, 1457=>347, 1458=>341, 1459=>341, 1460=>82, 1461=>211, 1462=>211, 1463=>200, + 1464=>200, 1465=>82, 1467=>341, 1468=>82, 1469=>82, 1470=>516, 1471=>200, 1472=>297, 1473=>1038, 1474=>1038, 1475=>333, 1476=>82, 1488=>714, 1489=>651, 1490=>557, 1491=>638, + 1492=>682, 1493=>297, 1494=>443, 1495=>682, 1496=>670, 1497=>284, 1498=>590, 1499=>595, 1500=>667, 1501=>683, 1502=>704, 1503=>297, 1504=>429, 1505=>670, 1506=>653, 1507=>661, + 1508=>660, 1509=>616, 1510=>671, 1511=>672, 1512=>600, 1513=>840, 1514=>756, 1520=>554, 1521=>550, 1522=>542, 1523=>238, 1524=>474, 1559=>556, 1560=>778, 1561=>944, 1562=>611, + 1563=>278, 1564=>889, 1569=>844, 1576=>923, 1578=>922, 1579=>922, 1581=>649, 1582=>704, 1587=>1221, 7936=>656, 7937=>656, 7938=>656, 7939=>656, 7940=>656, 7941=>656, 7942=>656, + 7943=>656, 7944=>722, 7945=>722, 7946=>722, 7947=>722, 7948=>722, 7949=>722, 7950=>722, 7951=>722, 7952=>570, 7953=>570, 7954=>570, 7955=>570, 7956=>570, 7957=>570, 7960=>667, + 7961=>667, 7962=>667, 7963=>667, 7964=>667, 7965=>667, 7968=>586, 7969=>586, 7970=>586, 7971=>586, 7972=>586, 7973=>586, 7974=>586, 7975=>586, 7976=>722, 7977=>722, 7978=>722, + 7979=>722, 7980=>722, 7981=>722, 7982=>722, 7983=>722, 7984=>346, 7985=>346, 7986=>346, 7987=>346, 7988=>346, 7989=>346, 7990=>346, 7991=>346, 7992=>278, 7993=>278, 7994=>278, + 7995=>278, 7996=>278, 7997=>278, 7998=>278, 7999=>278, 8000=>610, 8001=>610, 8002=>610, 8003=>610, 8004=>610, 8005=>610, 8008=>822, 8009=>822, 8010=>822, 8011=>822, 8012=>822, + 8013=>822, 8016=>575, 8017=>575, 8018=>575, 8019=>575, 8020=>575, 8021=>575, 8022=>575, 8023=>575, 8025=>804, 8027=>804, 8029=>804, 8031=>804, 8032=>800, 8033=>800, 8034=>800, + 8035=>800, 8036=>800, 8037=>800, 8038=>800, 8039=>800, 8040=>780, 8041=>780, 8042=>780, 8043=>780, 8044=>780, 8045=>780, 8046=>780, 8047=>780, 8048=>656, 8049=>656, 8050=>570, + 8051=>570, 8052=>586, 8053=>586, 8054=>346, 8055=>346, 8056=>610, 8057=>610, 8058=>575, 8059=>575, 8060=>800, 8061=>800, 8064=>656, 8065=>656, 8066=>656, 8067=>656, 8068=>656, + 8069=>656, 8070=>656, 8071=>656, 8072=>968, 8073=>968, 8074=>968, 8075=>968, 8076=>968, 8077=>968, 8078=>968, 8079=>968, 8080=>586, 8081=>586, 8082=>586, 8083=>586, 8084=>586, + 8085=>586, 8086=>586, 8087=>586, 8088=>968, 8089=>968, 8090=>968, 8091=>968, 8092=>968, 8093=>968, 8094=>968, 8095=>968, 8096=>800, 8097=>800, 8098=>800, 8099=>800, 8100=>800, + 8101=>800, 8102=>800, 8103=>800, 8104=>1026, 8105=>1026, 8106=>1026, 8107=>1026, 8108=>1026, 8109=>1026, 8110=>1026, 8111=>1026, 8112=>656, 8113=>656, 8114=>656, 8115=>656, 8116=>660, + 8118=>656, 8119=>656, 8120=>722, 8121=>722, 8122=>722, 8123=>722, 8124=>968, 8125=>278, 8126=>346, 8127=>278, 8128=>278, 8129=>333, 8130=>586, 8131=>586, 8132=>560, 8134=>586, + 8135=>586, 8136=>667, 8137=>667, 8138=>722, 8139=>722, 8140=>968, 8141=>492, 8142=>489, 8143=>394, 8144=>346, 8145=>346, 8146=>346, 8147=>346, 8150=>346, 8151=>346, 8152=>278, + 8153=>278, 8154=>278, 8155=>278, 8157=>481, 8158=>589, 8159=>333, 8160=>575, 8161=>575, 8162=>575, 8163=>575, 8164=>626, 8165=>626, 8166=>575, 8167=>575, 8168=>804, 8169=>804, + 8170=>804, 8171=>804, 8172=>698, 8173=>333, 8174=>333, 8175=>333, 8178=>800, 8179=>800, 8180=>1125, 8182=>800, 8183=>800, 8184=>822, 8185=>822, 8186=>780, 8187=>780, 8188=>1111, + 8189=>333, 8190=>278, 8260=>167, 8308=>351, 8321=>351, 8322=>351, 8323=>351, 8324=>351, 8362=>1049, 8543=>869, 8706=>490, 8710=>729, 8721=>711, 8722=>584, 8730=>542, 8800=>548, + 8804=>584, 8805=>584, 9674=>489, 63033=>556, 63034=>556, 63035=>556, 63036=>556, 63037=>556, 63038=>556, 63039=>556, 63040=>556, 63041=>556, 63171=>333, 63196=>556, 64257=>611, 64258=>611, + 64285=>284, 64286=>305, 64287=>542, 64288=>653, 64289=>964, 64290=>888, 64291=>932, 64292=>845, 64293=>917, 64294=>933, 64295=>850, 64296=>1006, 64297=>584, 64298=>840, 64299=>840, 64300=>840, + 64301=>840, 64302=>714, 64303=>714, 64304=>714, 64305=>651, 64306=>557, 64307=>638, 64308=>682, 64309=>367, 64310=>443, 64312=>670, 64313=>354, 64314=>590, 64315=>595, 64316=>667, 64318=>704, + 64320=>429, 64321=>670, 64323=>661, 64324=>660, 64326=>671, 64327=>672, 64328=>600, 64329=>840, 64330=>756, 64331=>297, 64332=>651, 64333=>595, 64334=>660, 64335=>714, 65182=>636} + font[:enc]=''; + font[:diff]=''; + font[:file]='FreeSansBold.z'; + font[:ctg]='FreeSansBold.ctg.z'; + font[:originalsize]=91432; +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/freesansbi.rb b/lib/plugins/rfpdf/lib/fonts/freesansbi.rb new file mode 100644 index 000000000..6bad1ada5 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freesansbi.rb @@ -0,0 +1,76 @@ +TCPDFFontDescriptor.define('freesansbi') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='FreeSansBoldOblique'; + font[:desc]={'Ascent'=>979,'Descent'=>-309,'CapHeight'=>979,'Flags'=>96,'FontBBox'=>'[-379 -309 1283 979]','ItalicAngle'=>-12,'StemV'=>120,'MissingWidth'=>600}; + font[:up]=-111; + font[:ut]=69; + font[:cw]={ + 13=>333, 32=>278, 33=>333, 34=>474, 35=>556, 36=>556, 37=>889, 38=>722, 39=>238, 40=>333, 41=>333, 42=>389, 43=>584, 44=>278, 45=>333, 46=>278, + 47=>278, 48=>556, 49=>556, 50=>556, 51=>556, 52=>556, 53=>556, 54=>556, 55=>556, 56=>556, 57=>556, 58=>333, 59=>333, 60=>584, 61=>584, 62=>584, + 63=>611, 64=>975, 65=>722, 66=>722, 67=>722, 68=>722, 69=>667, 70=>611, 71=>778, 72=>722, 73=>278, 74=>556, 75=>722, 76=>611, 77=>833, 78=>722, + 79=>778, 80=>667, 81=>778, 82=>722, 83=>667, 84=>611, 85=>722, 86=>667, 87=>944, 88=>667, 89=>667, 90=>611, 91=>333, 92=>278, 93=>333, 94=>584, + 95=>556, 96=>333, 97=>556, 98=>611, 99=>556, 100=>611, 101=>556, 102=>333, 103=>611, 104=>611, 105=>278, 106=>278, 107=>556, 108=>278, 109=>889, 110=>611, + 111=>611, 112=>611, 113=>611, 114=>389, 115=>556, 116=>333, 117=>611, 118=>556, 119=>778, 120=>556, 121=>556, 122=>500, 123=>389, 124=>280, 125=>389, 126=>584, + 8364=>556, 1027=>611, 8218=>278, 402=>556, 8222=>500, 8230=>1000, 8224=>556, 8225=>556, 710=>333, 8240=>1000, 352=>667, 8249=>333, 338=>1000, 1036=>722, 381=>611, 1039=>722, + 8216=>278, 8217=>278, 8220=>500, 8221=>500, 8226=>350, 8211=>556, 8212=>1000, 732=>333, 8482=>1000, 353=>556, 8250=>333, 339=>944, 1116=>556, 382=>500, 376=>667, 161=>333, + 162=>556, 163=>556, 164=>556, 165=>556, 166=>280, 167=>556, 168=>333, 169=>737, 170=>370, 171=>556, 172=>584, 174=>737, 175=>333, 176=>606, 177=>584, 178=>444, + 179=>444, 180=>333, 181=>611, 182=>556, 183=>278, 184=>333, 185=>444, 186=>365, 187=>556, 188=>1055, 189=>1055, 190=>1055, 191=>611, 192=>722, 193=>722, 194=>722, + 195=>722, 196=>722, 197=>722, 198=>1000, 199=>722, 200=>667, 201=>667, 202=>667, 203=>667, 204=>278, 205=>278, 206=>278, 207=>278, 208=>722, 209=>722, 210=>778, + 211=>778, 212=>778, 213=>778, 214=>778, 215=>584, 216=>778, 217=>722, 218=>722, 219=>722, 220=>722, 221=>667, 222=>667, 223=>611, 224=>556, 225=>556, 226=>556, + 227=>556, 228=>556, 229=>556, 230=>889, 231=>556, 232=>556, 233=>556, 234=>556, 235=>556, 236=>278, 237=>278, 238=>278, 239=>278, 240=>611, 241=>611, 242=>611, + 243=>611, 244=>611, 245=>611, 246=>611, 247=>584, 248=>611, 249=>611, 250=>611, 251=>611, 252=>611, 253=>556, 254=>611, 255=>556, 256=>722, 257=>556, 258=>722, + 259=>556, 260=>722, 261=>556, 262=>722, 263=>556, 264=>722, 265=>556, 266=>722, 267=>556, 268=>722, 269=>556, 270=>722, 271=>722, 272=>722, 273=>611, 274=>667, + 275=>556, 276=>667, 277=>556, 278=>667, 279=>556, 280=>667, 281=>556, 282=>667, 283=>556, 284=>778, 285=>611, 286=>778, 287=>611, 288=>778, 289=>611, 290=>778, + 291=>611, 292=>722, 293=>611, 294=>722, 295=>611, 296=>278, 297=>278, 298=>278, 299=>278, 300=>278, 301=>278, 302=>278, 303=>268, 304=>278, 305=>278, 306=>278, + 307=>278, 308=>556, 309=>278, 310=>722, 311=>556, 312=>529, 313=>611, 314=>278, 315=>611, 316=>278, 317=>611, 318=>384, 319=>611, 320=>556, 321=>611, 322=>278, + 323=>722, 324=>611, 325=>722, 326=>611, 327=>722, 328=>611, 329=>611, 330=>722, 331=>611, 332=>778, 333=>611, 334=>778, 335=>611, 336=>778, 337=>611, 340=>722, + 341=>389, 342=>722, 343=>389, 344=>722, 345=>389, 346=>667, 347=>556, 348=>667, 349=>556, 350=>667, 351=>556, 354=>611, 355=>333, 356=>611, 357=>404, 358=>611, + 359=>333, 360=>722, 361=>611, 362=>722, 363=>611, 364=>722, 365=>611, 366=>722, 367=>611, 368=>722, 369=>611, 370=>722, 371=>611, 372=>944, 373=>778, 374=>667, + 375=>556, 377=>611, 378=>500, 379=>611, 380=>500, 383=>333, 536=>667, 537=>556, 538=>611, 539=>333, 711=>333, 728=>333, 729=>333, 730=>333, 731=>333, 733=>333, + 768=>0, 769=>0, 770=>0, 771=>0, 772=>0, 774=>0, 775=>0, 776=>0, 778=>0, 779=>0, 780=>0, 783=>0, 785=>0, 787=>0, 788=>0, 884=>208, + 885=>247, 890=>364, 894=>333, 900=>308, 901=>446, 902=>688, 903=>418, 904=>642, 905=>743, 906=>228, 908=>754, 910=>736, 911=>743, 912=>346, 913=>764, 914=>688, + 915=>642, 916=>744, 917=>710, 918=>688, 919=>743, 920=>810, 921=>296, 922=>744, 923=>744, 924=>860, 925=>714, 926=>690, 927=>822, 928=>781, 929=>698, 931=>688, + 932=>688, 933=>744, 934=>777, 935=>783, 936=>805, 937=>780, 938=>296, 939=>744, 940=>640, 941=>530, 942=>597, 943=>339, 944=>575, 945=>656, 946=>576, 947=>591, + 948=>620, 949=>570, 950=>522, 951=>586, 952=>586, 953=>346, 954=>576, 955=>620, 956=>667, 957=>564, 958=>530, 959=>610, 960=>721, 961=>626, 962=>595, 963=>676, + 964=>592, 965=>575, 966=>801, 967=>632, 968=>722, 969=>800, 970=>346, 971=>575, 972=>609, 973=>604, 974=>769, 1024=>666, 1025=>666, 1026=>790, 1028=>722, 1029=>667, + 1030=>278, 1031=>278, 1032=>556, 1033=>1110, 1034=>1088, 1035=>790, 1037=>722, 1038=>718, 1040=>722, 1041=>722, 1042=>723, 1043=>611, 1044=>918, 1045=>666, 1046=>1054, 1047=>659, + 1048=>722, 1049=>722, 1050=>720, 1051=>722, 1052=>843, 1053=>722, 1054=>778, 1055=>722, 1056=>649, 1057=>837, 1058=>611, 1059=>698, 1060=>902, 1061=>664, 1062=>730, 1063=>671, + 1064=>1101, 1065=>1179, 1066=>816, 1067=>939, 1068=>639, 1069=>737, 1070=>1080, 1071=>690, 1072=>554, 1073=>611, 1074=>621, 1075=>475, 1076=>804, 1077=>552, 1078=>775, 1079=>556, + 1080=>636, 1081=>636, 1082=>529, 1083=>608, 1084=>697, 1085=>636, 1086=>611, 1087=>636, 1088=>611, 1089=>554, 1090=>454, 1091=>552, 1092=>989, 1093=>554, 1094=>690, 1095=>606, + 1096=>934, 1097=>987, 1098=>741, 1099=>839, 1100=>619, 1101=>575, 1102=>908, 1103=>636, 1104=>552, 1105=>552, 1106=>606, 1107=>454, 1108=>556, 1109=>556, 1110=>278, 1111=>278, + 1112=>278, 1113=>900, 1114=>611, 1115=>606, 1117=>636, 1118=>556, 1119=>636, 1164=>639, 1165=>619, 1166=>649, 1167=>611, 1168=>611, 1169=>454, 1170=>611, 1171=>475, 1172=>611, + 1173=>475, 1174=>1054, 1175=>775, 1176=>659, 1177=>556, 1178=>720, 1179=>529, 1180=>720, 1181=>529, 1182=>720, 1183=>529, 1184=>720, 1185=>529, 1186=>722, 1187=>636, 1188=>722, + 1189=>636, 1190=>722, 1191=>636, 1192=>837, 1193=>554, 1194=>837, 1195=>554, 1196=>611, 1197=>454, 1198=>667, 1199=>556, 1200=>667, 1201=>556, 1202=>664, 1203=>554, 1204=>730, + 1205=>690, 1206=>671, 1207=>606, 1208=>671, 1209=>606, 1210=>671, 1211=>606, 1212=>837, 1213=>554, 1214=>837, 1215=>554, 1216=>278, 1217=>1054, 1218=>775, 1219=>720, 1220=>529, + 1223=>722, 1224=>636, 1227=>671, 1228=>606, 1232=>722, 1233=>554, 1234=>722, 1235=>554, 1236=>1000, 1237=>889, 1238=>666, 1239=>552, 1240=>837, 1241=>554, 1242=>837, 1243=>554, + 1244=>1054, 1245=>775, 1246=>659, 1247=>556, 1248=>659, 1249=>556, 1250=>722, 1251=>636, 1252=>722, 1253=>636, 1254=>778, 1255=>611, 1256=>778, 1257=>611, 1258=>778, 1259=>611, + 1260=>737, 1261=>575, 1262=>698, 1263=>552, 1264=>698, 1265=>552, 1266=>698, 1267=>552, 1268=>671, 1269=>606, 1272=>939, 1273=>839, 1456=>82, 1457=>347, 1458=>341, 1459=>341, + 1460=>82, 1461=>211, 1462=>211, 1463=>200, 1464=>200, 1465=>82, 1467=>341, 1468=>82, 1469=>82, 1470=>516, 1471=>200, 1472=>297, 1473=>1038, 1474=>1038, 1475=>333, 1476=>82, + 1488=>714, 1489=>651, 1490=>557, 1491=>638, 1492=>682, 1493=>297, 1494=>443, 1495=>682, 1496=>670, 1497=>284, 1498=>590, 1499=>595, 1500=>667, 1501=>683, 1502=>704, 1503=>297, + 1504=>429, 1505=>670, 1506=>653, 1507=>661, 1508=>660, 1509=>616, 1510=>671, 1511=>672, 1512=>600, 1513=>840, 1514=>756, 1520=>554, 1521=>550, 1522=>542, 1523=>238, 1524=>474, + 7936=>656, 7937=>656, 7938=>656, 7939=>656, 7940=>656, 7941=>656, 7942=>656, 7943=>656, 7944=>764, 7945=>764, 7946=>764, 7947=>764, 7948=>764, 7949=>764, 7950=>764, 7951=>764, + 7952=>570, 7953=>570, 7954=>570, 7955=>570, 7956=>570, 7957=>570, 7960=>710, 7961=>710, 7962=>710, 7963=>710, 7964=>710, 7965=>710, 7968=>586, 7969=>586, 7970=>586, 7971=>586, + 7972=>586, 7973=>586, 7974=>586, 7975=>586, 7976=>743, 7977=>743, 7978=>743, 7979=>743, 7980=>743, 7981=>743, 7982=>743, 7983=>743, 7984=>346, 7985=>346, 7986=>346, 7987=>346, + 7988=>346, 7989=>346, 7990=>346, 7991=>346, 7992=>296, 7993=>296, 7994=>296, 7995=>296, 7996=>296, 7997=>296, 7998=>296, 7999=>296, 8000=>610, 8001=>610, 8002=>610, 8003=>610, + 8004=>610, 8005=>610, 8008=>822, 8009=>822, 8010=>822, 8011=>822, 8012=>822, 8013=>822, 8016=>575, 8017=>575, 8018=>575, 8019=>575, 8020=>575, 8021=>575, 8022=>575, 8023=>575, + 8025=>744, 8027=>744, 8029=>744, 8031=>744, 8032=>800, 8033=>800, 8034=>800, 8035=>800, 8036=>800, 8037=>800, 8038=>800, 8039=>800, 8040=>780, 8041=>780, 8042=>780, 8043=>780, + 8044=>780, 8045=>780, 8046=>780, 8047=>780, 8048=>656, 8049=>656, 8050=>570, 8051=>570, 8052=>586, 8053=>586, 8054=>346, 8055=>346, 8056=>610, 8057=>610, 8058=>575, 8059=>575, + 8060=>800, 8061=>800, 8064=>656, 8065=>656, 8066=>656, 8067=>656, 8068=>656, 8069=>656, 8070=>656, 8071=>656, 8072=>1007, 8073=>1007, 8074=>1007, 8075=>1007, 8076=>1007, 8077=>1007, + 8078=>1007, 8079=>1007, 8080=>586, 8081=>586, 8082=>586, 8083=>586, 8084=>586, 8085=>586, 8086=>586, 8087=>586, 8088=>986, 8089=>986, 8090=>986, 8091=>986, 8092=>986, 8093=>986, + 8094=>986, 8095=>986, 8096=>800, 8097=>800, 8098=>800, 8099=>800, 8100=>800, 8101=>800, 8102=>800, 8103=>800, 8104=>1023, 8105=>1023, 8106=>1023, 8107=>1023, 8108=>1023, 8109=>1023, + 8110=>1023, 8111=>1023, 8112=>656, 8113=>656, 8114=>656, 8115=>656, 8116=>640, 8118=>656, 8119=>656, 8120=>764, 8121=>764, 8122=>764, 8123=>764, 8124=>1007, 8125=>278, 8126=>201, + 8127=>147, 8128=>278, 8129=>333, 8130=>586, 8131=>586, 8132=>597, 8134=>586, 8135=>586, 8136=>710, 8137=>710, 8138=>743, 8139=>743, 8140=>986, 8141=>402, 8142=>403, 8143=>147, + 8144=>346, 8145=>346, 8146=>346, 8147=>346, 8150=>346, 8151=>346, 8152=>296, 8153=>296, 8154=>296, 8155=>296, 8157=>434, 8158=>433, 8159=>333, 8160=>575, 8161=>575, 8162=>575, + 8163=>575, 8164=>626, 8165=>626, 8166=>575, 8167=>575, 8168=>744, 8169=>744, 8173=>333, 8174=>351, 8175=>303, 8182=>800, 8183=>800, 8184=>822, 8185=>822, 8186=>780, 8187=>780, + 8188=>1023, 8189=>333, 8190=>159, 8260=>167, 8263=>1222, 8264=>944, 8265=>944, 8362=>1049, 8706=>490, 8710=>729, 8721=>711, 8722=>584, 8730=>542, 8800=>584, 8804=>584, 8805=>584, + 9674=>489, 63033=>556, 63034=>556, 63035=>556, 63036=>556, 63037=>556, 63038=>556, 63039=>556, 63040=>556, 63041=>556, 63166=>278, 63171=>333, 63196=>556, 64256=>666, 64257=>611, 64258=>611, + 64259=>944, 64260=>944, 64261=>666, 64262=>889, 64285=>284, 64286=>305, 64287=>542, 64288=>653, 64289=>964, 64290=>888, 64291=>932, 64292=>845, 64293=>917, 64294=>933, 64295=>850, 64296=>1006, + 64297=>584, 64298=>840, 64299=>840, 64300=>840, 64301=>840, 64302=>714, 64303=>714, 64304=>714, 64305=>651, 64306=>557, 64307=>638, 64308=>682, 64309=>367, 64310=>443, 64312=>670, 64313=>354, + 64314=>590, 64315=>595, 64316=>667, 64318=>704, 64320=>429, 64321=>670, 64323=>661, 64324=>660, 64326=>671, 64327=>672, 64328=>600, 64329=>840, 64330=>756, 64331=>297, 64332=>651, 64333=>595, + 64334=>660, 64335=>714}; + font[:enc]=''; + font[:diff]=''; + font[:file]='FreeSansBoldOblique.z'; + font[:ctg]='FreeSansBoldOblique.ctg.z'; + font[:originalsize]=95508; +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/freesansi.rb b/lib/plugins/rfpdf/lib/fonts/freesansi.rb new file mode 100644 index 000000000..1766e2471 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/freesansi.rb @@ -0,0 +1,85 @@ +TCPDFFontDescriptor.define('freesansi') do |font| + font[:type]='TrueTypeUnicode'; + font[:name]='FreeSansOblique'; + font[:desc]={'Ascent'=>1141,'Descent'=>-419,'CapHeight'=>1141,'Flags'=>96,'FontBBox'=>'[-313 -419 1129 1141]','ItalicAngle'=>-12,'StemV'=>70,'MissingWidth'=>600}; + font[:up]=-151; + font[:ut]=50; + font[:cw]={ + 13=>333, 32=>278, 33=>278, 34=>355, 35=>556, 36=>556, 37=>889, 38=>667, 39=>191, 40=>333, 41=>333, 42=>389, 43=>584, 44=>278, 45=>333, 46=>278, + 47=>278, 48=>556, 49=>556, 50=>556, 51=>556, 52=>556, 53=>556, 54=>556, 55=>556, 56=>556, 57=>556, 58=>278, 59=>278, 60=>584, 61=>584, 62=>584, + 63=>556, 64=>1015, 65=>667, 66=>667, 67=>722, 68=>722, 69=>667, 70=>611, 71=>778, 72=>722, 73=>278, 74=>500, 75=>667, 76=>556, 77=>833, 78=>722, + 79=>778, 80=>667, 81=>778, 82=>722, 83=>667, 84=>611, 85=>722, 86=>667, 87=>944, 88=>667, 89=>667, 90=>611, 91=>278, 92=>278, 93=>278, 94=>469, + 95=>556, 96=>333, 97=>556, 98=>556, 99=>500, 100=>556, 101=>556, 102=>278, 103=>556, 104=>556, 105=>222, 106=>222, 107=>500, 108=>222, 109=>833, 110=>556, + 111=>556, 112=>556, 113=>556, 114=>333, 115=>500, 116=>278, 117=>556, 118=>500, 119=>722, 120=>500, 121=>500, 122=>500, 123=>334, 124=>260, 125=>334, 126=>584, + 8364=>556, 1027=>611, 8218=>222, 402=>556, 8222=>333, 8230=>1000, 8224=>556, 8225=>556, 710=>333, 8240=>1000, 352=>667, 8249=>333, 338=>1000, 1036=>667, 381=>611, 1039=>722, + 8216=>222, 8217=>222, 8220=>333, 8221=>333, 8226=>350, 8211=>556, 8212=>1000, 732=>333, 8482=>1000, 353=>500, 8250=>333, 339=>944, 1116=>500, 382=>500, 376=>667, 161=>333, + 162=>556, 163=>556, 164=>556, 165=>556, 166=>260, 167=>556, 168=>333, 169=>737, 170=>370, 171=>556, 172=>584, 173=>333, 174=>737, 175=>333, 176=>606, 177=>584, + 178=>390, 179=>390, 180=>333, 181=>556, 182=>537, 183=>278, 184=>333, 185=>390, 186=>365, 187=>556, 188=>947, 189=>947, 190=>947, 191=>611, 192=>667, 193=>667, + 194=>667, 195=>667, 196=>667, 197=>667, 198=>1000, 199=>722, 200=>667, 201=>667, 202=>667, 203=>667, 204=>278, 205=>278, 206=>278, 207=>278, 208=>722, 209=>722, + 210=>778, 211=>778, 212=>778, 213=>778, 214=>778, 215=>584, 216=>778, 217=>722, 218=>722, 219=>722, 220=>722, 221=>667, 222=>667, 223=>611, 224=>556, 225=>556, + 226=>556, 227=>556, 228=>556, 229=>556, 230=>889, 231=>500, 232=>556, 233=>556, 234=>556, 235=>556, 236=>278, 237=>278, 238=>278, 239=>278, 240=>556, 241=>556, + 242=>556, 243=>556, 244=>556, 245=>556, 246=>556, 247=>584, 248=>611, 249=>556, 250=>556, 251=>556, 252=>556, 253=>500, 254=>556, 255=>500, 256=>667, 257=>556, + 258=>667, 259=>556, 260=>667, 261=>556, 262=>722, 263=>500, 264=>722, 265=>500, 266=>722, 267=>500, 268=>722, 269=>500, 270=>722, 271=>650, 272=>722, 273=>556, + 274=>667, 275=>556, 276=>667, 277=>556, 278=>667, 279=>556, 280=>667, 281=>556, 282=>667, 283=>556, 284=>778, 285=>556, 286=>778, 287=>556, 288=>778, 289=>556, + 290=>778, 291=>527, 292=>722, 293=>556, 294=>722, 295=>556, 296=>278, 297=>278, 298=>278, 299=>222, 300=>278, 301=>278, 302=>278, 303=>222, 304=>278, 305=>278, + 306=>742, 307=>362, 308=>500, 309=>222, 310=>667, 311=>500, 312=>510, 313=>556, 314=>222, 315=>556, 316=>222, 317=>556, 318=>307, 319=>556, 320=>500, 321=>556, + 322=>222, 323=>722, 324=>556, 325=>722, 326=>556, 327=>722, 328=>556, 329=>556, 330=>722, 331=>556, 332=>778, 333=>556, 334=>778, 335=>556, 336=>778, 337=>556, + 340=>722, 341=>333, 342=>722, 343=>333, 344=>722, 345=>333, 346=>667, 347=>500, 348=>667, 349=>500, 350=>667, 351=>500, 354=>611, 355=>278, 356=>611, 357=>319, + 358=>611, 359=>278, 360=>722, 361=>556, 362=>722, 363=>556, 364=>722, 365=>556, 366=>722, 367=>556, 368=>722, 369=>556, 370=>722, 371=>556, 372=>944, 373=>722, + 374=>667, 375=>500, 377=>611, 378=>500, 379=>611, 380=>500, 383=>278, 461=>667, 462=>556, 463=>278, 464=>278, 465=>778, 466=>556, 467=>722, 468=>556, 469=>722, + 470=>556, 471=>722, 472=>556, 473=>722, 474=>556, 475=>722, 476=>556, 478=>667, 479=>556, 482=>1000, 483=>889, 486=>778, 487=>556, 488=>667, 489=>500, 490=>778, + 491=>556, 492=>778, 493=>556, 496=>222, 500=>778, 501=>556, 504=>722, 505=>556, 506=>667, 507=>556, 508=>1000, 509=>889, 510=>778, 511=>611, 512=>667, 513=>556, + 514=>667, 515=>556, 516=>667, 517=>556, 518=>667, 519=>556, 520=>278, 521=>278, 522=>278, 523=>278, 524=>778, 525=>556, 526=>778, 527=>556, 528=>722, 529=>333, + 530=>722, 531=>333, 532=>722, 533=>556, 534=>722, 535=>556, 536=>667, 537=>500, 538=>611, 539=>278, 711=>333, 728=>333, 729=>333, 730=>333, 731=>333, 733=>333, + 768=>0, 769=>0, 770=>0, 771=>0, 772=>0, 774=>0, 775=>0, 776=>0, 778=>0, 779=>0, 783=>0, 785=>0, 787=>0, 788=>0, 884=>199, 885=>199, + 890=>332, 894=>278, 900=>291, 901=>624, 902=>659, 903=>358, 904=>657, 905=>678, 906=>183, 908=>729, 910=>699, 911=>747, 912=>286, 913=>684, 914=>628, 915=>582, + 916=>684, 917=>650, 918=>628, 919=>683, 920=>750, 921=>236, 922=>684, 923=>684, 924=>800, 925=>654, 926=>630, 927=>750, 928=>721, 929=>638, 931=>628, 932=>628, + 933=>684, 934=>717, 935=>723, 936=>745, 937=>720, 938=>236, 939=>684, 940=>593, 941=>519, 942=>595, 943=>271, 944=>515, 945=>596, 946=>516, 947=>531, 948=>560, + 949=>510, 950=>462, 951=>526, 952=>526, 953=>286, 954=>516, 955=>560, 956=>607, 957=>504, 958=>470, 959=>550, 960=>661, 961=>566, 962=>535, 963=>616, 964=>532, + 965=>515, 966=>741, 967=>572, 968=>662, 969=>740, 970=>286, 971=>515, 972=>535, 973=>503, 974=>725, 1024=>667, 1025=>667, 1026=>766, 1028=>722, 1029=>667, 1030=>278, + 1031=>278, 1032=>500, 1033=>968, 1034=>1173, 1035=>766, 1037=>731, 1038=>650, 1040=>667, 1041=>639, 1042=>667, 1043=>611, 1044=>816, 1045=>667, 1046=>897, 1047=>652, 1048=>731, + 1049=>731, 1050=>664, 1051=>646, 1052=>833, 1053=>722, 1054=>778, 1055=>722, 1056=>667, 1057=>722, 1058=>611, 1059=>530, 1060=>891, 1061=>667, 1062=>722, 1063=>642, 1064=>836, + 1065=>837, 1066=>866, 1067=>886, 1068=>698, 1069=>717, 1070=>1079, 1071=>691, 1072=>556, 1073=>556, 1074=>538, 1075=>430, 1076=>640, 1077=>556, 1078=>818, 1079=>495, 1080=>560, + 1081=>560, 1082=>510, 1083=>556, 1084=>621, 1085=>561, 1086=>556, 1087=>560, 1088=>556, 1089=>500, 1090=>400, 1091=>500, 1092=>916, 1093=>500, 1094=>560, 1095=>497, 1096=>695, + 1097=>695, 1098=>640, 1099=>734, 1100=>523, 1101=>534, 1102=>788, 1103=>564, 1104=>556, 1105=>556, 1106=>568, 1107=>430, 1108=>500, 1109=>500, 1110=>222, 1111=>278, 1112=>222, + 1113=>840, 1114=>850, 1115=>568, 1117=>560, 1118=>500, 1119=>560, 1164=>698, 1165=>523, 1166=>667, 1167=>556, 1168=>611, 1169=>430, 1170=>611, 1171=>430, 1172=>611, 1173=>430, + 1174=>897, 1175=>818, 1176=>652, 1177=>495, 1178=>664, 1179=>510, 1180=>664, 1181=>510, 1182=>664, 1183=>510, 1184=>664, 1185=>510, 1186=>722, 1187=>561, 1188=>722, 1189=>561, + 1190=>722, 1191=>560, 1192=>722, 1193=>495, 1194=>722, 1195=>495, 1196=>611, 1197=>400, 1198=>667, 1199=>500, 1200=>667, 1201=>500, 1202=>665, 1203=>496, 1204=>722, 1205=>560, + 1206=>642, 1207=>497, 1208=>642, 1209=>497, 1210=>642, 1211=>497, 1212=>722, 1213=>495, 1214=>722, 1215=>495, 1216=>278, 1217=>897, 1218=>818, 1219=>664, 1220=>510, 1223=>722, + 1224=>561, 1227=>642, 1228=>497, 1232=>667, 1233=>556, 1234=>667, 1235=>556, 1236=>1000, 1237=>889, 1238=>667, 1239=>556, 1240=>722, 1241=>495, 1242=>722, 1243=>495, 1244=>897, + 1245=>818, 1246=>652, 1247=>495, 1248=>652, 1249=>495, 1250=>731, 1251=>560, 1252=>731, 1253=>560, 1254=>778, 1255=>556, 1256=>780, 1257=>554, 1258=>780, 1259=>554, 1260=>717, + 1261=>534, 1262=>530, 1263=>500, 1264=>530, 1265=>500, 1266=>530, 1267=>500, 1268=>642, 1269=>497, 1272=>886, 1273=>734, 1329=>722, 1330=>705, 1331=>774, 1332=>754, 1333=>722, + 1334=>751, 1335=>485, 1336=>722, 1337=>782, 1338=>655, 1339=>699, 1340=>417, 1341=>853, 1342=>791, 1343=>711, 1344=>588, 1345=>663, 1346=>665, 1347=>665, 1348=>756, 1349=>623, + 1350=>773, 1351=>603, 1352=>722, 1353=>648, 1354=>722, 1355=>751, 1356=>750, 1357=>722, 1358=>748, 1359=>667, 1360=>699, 1361=>623, 1362=>417, 1363=>785, 1364=>638, 1365=>778, + 1366=>716, 1370=>222, 1371=>133, 1372=>325, 1373=>333, 1374=>344, 1377=>833, 1378=>556, 1379=>572, 1380=>581, 1381=>550, 1382=>588, 1383=>448, 1384=>556, 1385=>568, 1386=>582, + 1387=>545, 1388=>301, 1389=>799, 1390=>556, 1391=>554, 1392=>533, 1393=>548, 1394=>552, 1395=>552, 1396=>544, 1397=>222, 1398=>544, 1399=>456, 1400=>556, 1401=>390, 1402=>833, + 1403=>509, 1404=>547, 1405=>533, 1406=>610, 1407=>887, 1408=>556, 1409=>545, 1410=>352, 1411=>853, 1412=>588, 1413=>579, 1414=>690, 1415=>545, 1417=>278, 1418=>367, 1456=>70, + 1457=>335, 1458=>329, 1459=>329, 1460=>70, 1461=>200, 1462=>200, 1463=>188, 1464=>188, 1465=>70, 1467=>329, 1468=>70, 1469=>70, 1470=>488, 1471=>200, 1472=>212, 1473=>0, + 1474=>0, 1475=>278, 1476=>70, 1488=>640, 1489=>591, 1490=>466, 1491=>598, 1492=>622, 1493=>212, 1494=>351, 1495=>623, 1496=>608, 1497=>200, 1498=>526, 1499=>550, 1500=>600, + 1501=>623, 1502=>621, 1503=>212, 1504=>378, 1505=>607, 1506=>587, 1507=>575, 1508=>568, 1509=>540, 1510=>590, 1511=>606, 1512=>547, 1513=>776, 1514=>687, 1520=>424, 1521=>412, + 1522=>400, 1523=>184, 1524=>344, 7936=>596, 7937=>596, 7938=>596, 7939=>596, 7940=>596, 7941=>596, 7942=>596, 7943=>596, 7944=>684, 7945=>684, 7946=>684, 7947=>684, 7948=>684, + 7949=>684, 7950=>684, 7951=>684, 7952=>510, 7953=>510, 7954=>510, 7955=>510, 7956=>510, 7957=>510, 7960=>650, 7961=>650, 7962=>650, 7963=>650, 7964=>650, 7965=>650, 7968=>526, + 7969=>526, 7970=>526, 7971=>526, 7972=>526, 7973=>526, 7974=>526, 7975=>526, 7976=>683, 7977=>683, 7978=>683, 7979=>683, 7980=>683, 7981=>683, 7982=>683, 7983=>683, 7984=>286, + 7985=>286, 7986=>286, 7987=>286, 7988=>286, 7989=>286, 7990=>286, 7991=>286, 7992=>236, 7993=>236, 7994=>236, 7995=>236, 7996=>236, 7997=>236, 7998=>236, 7999=>236, 8000=>550, + 8001=>550, 8002=>550, 8003=>550, 8004=>550, 8005=>550, 8008=>750, 8009=>750, 8010=>750, 8011=>750, 8012=>750, 8013=>750, 8016=>515, 8017=>515, 8018=>515, 8019=>515, 8020=>515, + 8021=>515, 8022=>515, 8023=>515, 8025=>684, 8027=>684, 8029=>684, 8031=>684, 8032=>740, 8033=>740, 8034=>740, 8035=>740, 8036=>740, 8037=>740, 8038=>740, 8039=>740, 8040=>720, + 8041=>720, 8042=>720, 8043=>720, 8044=>720, 8045=>720, 8046=>720, 8047=>720, 8048=>596, 8049=>596, 8050=>510, 8051=>510, 8052=>526, 8053=>526, 8054=>286, 8055=>286, 8056=>550, + 8057=>550, 8058=>515, 8059=>515, 8060=>740, 8061=>740, 8064=>596, 8065=>596, 8066=>596, 8067=>596, 8068=>596, 8069=>596, 8070=>596, 8071=>596, 8072=>900, 8073=>900, 8074=>900, + 8075=>900, 8076=>900, 8077=>900, 8078=>900, 8079=>900, 8080=>526, 8081=>526, 8082=>526, 8083=>526, 8084=>526, 8085=>526, 8086=>526, 8087=>526, 8088=>899, 8089=>899, 8090=>899, + 8091=>899, 8092=>899, 8093=>899, 8094=>899, 8095=>899, 8096=>740, 8097=>740, 8098=>740, 8099=>740, 8100=>740, 8101=>740, 8102=>740, 8103=>740, 8104=>936, 8105=>936, 8106=>936, + 8107=>936, 8108=>936, 8109=>936, 8110=>936, 8111=>936, 8112=>596, 8113=>596, 8114=>596, 8115=>596, 8116=>593, 8118=>596, 8119=>596, 8120=>684, 8121=>684, 8122=>684, 8123=>684, + 8124=>900, 8125=>278, 8126=>201, 8127=>147, 8128=>278, 8129=>333, 8130=>526, 8131=>526, 8132=>595, 8134=>526, 8135=>526, 8136=>650, 8137=>650, 8138=>683, 8139=>683, 8140=>899, + 8141=>602, 8142=>601, 8143=>333, 8144=>286, 8145=>286, 8146=>286, 8147=>286, 8150=>286, 8151=>286, 8152=>236, 8153=>236, 8154=>236, 8155=>236, 8157=>434, 8158=>433, 8159=>333, + 8160=>515, 8161=>515, 8162=>515, 8163=>515, 8164=>566, 8165=>566, 8166=>515, 8167=>515, 8168=>684, 8169=>684, 8170=>684, 8171=>684, 8172=>638, 8173=>333, 8174=>624, 8175=>303, + 8178=>740, 8179=>740, 8180=>725, 8182=>740, 8183=>740, 8184=>750, 8185=>750, 8186=>720, 8187=>720, 8188=>936, 8189=>333, 8190=>159, 8260=>167, 8362=>869, 8706=>490, 8710=>712, + 8721=>711, 8722=>584, 8730=>542, 8800=>584, 8804=>584, 8805=>584, 9674=>489, 63033=>556, 63034=>556, 63035=>556, 63036=>556, 63037=>556, 63038=>556, 63039=>556, 63040=>556, 63041=>556, + 63166=>222, 63171=>333, 63196=>556, 64256=>556, 64257=>500, 64258=>500, 64259=>778, 64260=>778, 64261=>556, 64262=>778, 64285=>200, 64286=>305, 64287=>400, 64288=>587, 64289=>890, 64290=>848, + 64291=>872, 64292=>800, 64293=>850, 64294=>873, 64295=>797, 64296=>937, 64297=>584, 64298=>776, 64299=>776, 64300=>776, 64301=>776, 64302=>640, 64303=>640, 64304=>640, 64305=>591, 64306=>466, + 64307=>598, 64308=>622, 64309=>262, 64310=>351, 64312=>608, 64313=>270, 64314=>526, 64315=>550, 64316=>600, 64318=>621, 64320=>378, 64321=>607, 64323=>575, 64324=>568, 64326=>590, 64327=>606, + 64328=>547, 64329=>776, 64330=>687, 64331=>212, 64332=>591, 64333=>550, 64334=>568, 64335=>640}; + font[:enc]=''; + font[:diff]=''; + font[:file]='FreeSansOblique.z'; + font[:ctg]='FreeSansOblique.ctg.z'; + font[:originalsize]=110740; +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/helvetica.rb b/lib/plugins/rfpdf/lib/fonts/helvetica.rb new file mode 100644 index 000000000..6d9ee83e5 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/helvetica.rb @@ -0,0 +1,4 @@ +TCPDFFontDescriptor.define('helvetica') do |font| + font[:cw]={ + 0.chr=>278, 1.chr=>278, 2.chr=>278, 3.chr=>278, 4.chr=>278, 5.chr=>278, 6.chr=>278, 7.chr=>278, 8.chr=>278, 9.chr=>278, 10.chr=>278, 11.chr=>278, 12.chr=>278, 13.chr=>278, 14.chr=>278, 15.chr=>278, 16.chr=>278, 17.chr=>278, 18.chr=>278, 19.chr=>278, 20.chr=>278, 21.chr=>278, 22.chr=>278, 23.chr=>278, 24.chr=>278, 25.chr=>278, 26.chr=>278, 27.chr=>278, 28.chr=>278, 29.chr=>278, 30.chr=>278, 31.chr=>278, ' '=>278, '!'=>278, '"'=>355, '#'=>556, '$'=>556, '%'=>889, '&'=>667, '\''=>191, '('=>333, ')'=>333, '*'=>389, '+'=>584, ','=>278, '-'=>333, '.'=>278, '/'=>278, '0'=>556, '1'=>556, '2'=>556, '3'=>556, '4'=>556, '5'=>556, '6'=>556, '7'=>556, '8'=>556, '9'=>556, ':'=>278, ';'=>278, '<'=>584, '='=>584, '>'=>584, '?'=>556, '@'=>1015, 'A'=>667, 'B'=>667, 'C'=>722, 'D'=>722, 'E'=>667, 'F'=>611, 'G'=>778, 'H'=>722, 'I'=>278, 'J'=>500, 'K'=>667, 'L'=>556, 'M'=>833, 'N'=>722, 'O'=>778, 'P'=>667, 'Q'=>778, 'R'=>722, 'S'=>667, 'T'=>611, 'U'=>722, 'V'=>667, 'W'=>944, 'X'=>667, 'Y'=>667, 'Z'=>611, '['=>278, '\\'=>278, ']'=>278, '^'=>469, '_'=>556, '`'=>333, 'a'=>556, 'b'=>556, 'c'=>500, 'd'=>556, 'e'=>556, 'f'=>278, 'g'=>556, 'h'=>556, 'i'=>222, 'j'=>222, 'k'=>500, 'l'=>222, 'm'=>833, 'n'=>556, 'o'=>556, 'p'=>556, 'q'=>556, 'r'=>333, 's'=>500, 't'=>278, 'u'=>556, 'v'=>500, 'w'=>722, 'x'=>500, 'y'=>500, 'z'=>500, '{'=>334, '|'=>260, '}'=>334, '~'=>584, 127.chr=>350, 128.chr=>556, 129.chr=>350, 130.chr=>222, 131.chr=>556, 132.chr=>333, 133.chr=>1000, 134.chr=>556, 135.chr=>556, 136.chr=>333, 137.chr=>1000, 138.chr=>667, 139.chr=>333, 140.chr=>1000, 141.chr=>350, 142.chr=>611, 143.chr=>350, 144.chr=>350, 145.chr=>222, 146.chr=>222, 147.chr=>333, 148.chr=>333, 149.chr=>350, 150.chr=>556, 151.chr=>1000, 152.chr=>333, 153.chr=>1000, 154.chr=>500, 155.chr=>333, 156.chr=>944, 157.chr=>350, 158.chr=>500, 159.chr=>667, 160.chr=>278, 161.chr=>333, 162.chr=>556, 163.chr=>556, 164.chr=>556, 165.chr=>556, 166.chr=>260, 167.chr=>556, 168.chr=>333, 169.chr=>737, 170.chr=>370, 171.chr=>556, 172.chr=>584, 173.chr=>333, 174.chr=>737, 175.chr=>333, 176.chr=>400, 177.chr=>584, 178.chr=>333, 179.chr=>333, 180.chr=>333, 181.chr=>556, 182.chr=>537, 183.chr=>278, 184.chr=>333, 185.chr=>333, 186.chr=>365, 187.chr=>556, 188.chr=>834, 189.chr=>834, 190.chr=>834, 191.chr=>611, 192.chr=>667, 193.chr=>667, 194.chr=>667, 195.chr=>667, 196.chr=>667, 197.chr=>667, 198.chr=>1000, 199.chr=>722, 200.chr=>667, 201.chr=>667, 202.chr=>667, 203.chr=>667, 204.chr=>278, 205.chr=>278, 206.chr=>278, 207.chr=>278, 208.chr=>722, 209.chr=>722, 210.chr=>778, 211.chr=>778, 212.chr=>778, 213.chr=>778, 214.chr=>778, 215.chr=>584, 216.chr=>778, 217.chr=>722, 218.chr=>722, 219.chr=>722, 220.chr=>722, 221.chr=>667, 222.chr=>667, 223.chr=>611, 224.chr=>556, 225.chr=>556, 226.chr=>556, 227.chr=>556, 228.chr=>556, 229.chr=>556, 230.chr=>889, 231.chr=>500, 232.chr=>556, 233.chr=>556, 234.chr=>556, 235.chr=>556, 236.chr=>278, 237.chr=>278, 238.chr=>278, 239.chr=>278, 240.chr=>556, 241.chr=>556, 242.chr=>556, 243.chr=>556, 244.chr=>556, 245.chr=>556, 246.chr=>556, 247.chr=>584, 248.chr=>611, 249.chr=>556, 250.chr=>556, 251.chr=>556, 252.chr=>556, 253.chr=>500, 254.chr=>556, 255.chr=>500} +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/helveticab.rb b/lib/plugins/rfpdf/lib/fonts/helveticab.rb new file mode 100644 index 000000000..879ca7a0b --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/helveticab.rb @@ -0,0 +1,15 @@ +TCPDFFontDescriptor.define('helveticab') do |font| + font[:cw]={ + 0.chr=>278,1.chr=>278,2.chr=>278,3.chr=>278,4.chr=>278,5.chr=>278,6.chr=>278,7.chr=>278,8.chr=>278,9.chr=>278,10.chr=>278,11.chr=>278,12.chr=>278,13.chr=>278,14.chr=>278,15.chr=>278,16.chr=>278,17.chr=>278,18.chr=>278,19.chr=>278,20.chr=>278,21.chr=>278, + 22.chr=>278,23.chr=>278,24.chr=>278,25.chr=>278,26.chr=>278,27.chr=>278,28.chr=>278,29.chr=>278,30.chr=>278,31.chr=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, + 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889, + 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,127.chr=>350,128.chr=>556,129.chr=>350,130.chr=>278,131.chr=>556, + 132.chr=>500,133.chr=>1000,134.chr=>556,135.chr=>556,136.chr=>333,137.chr=>1000,138.chr=>667,139.chr=>333,140.chr=>1000,141.chr=>350,142.chr=>611,143.chr=>350,144.chr=>350,145.chr=>278,146.chr=>278,147.chr=>500,148.chr=>500,149.chr=>350,150.chr=>556,151.chr=>1000,152.chr=>333,153.chr=>1000, + 154.chr=>556,155.chr=>333,156.chr=>944,157.chr=>350,158.chr=>500,159.chr=>667,160.chr=>278,161.chr=>333,162.chr=>556,163.chr=>556,164.chr=>556,165.chr=>556,166.chr=>280,167.chr=>556,168.chr=>333,169.chr=>737,170.chr=>370,171.chr=>556,172.chr=>584,173.chr=>333,174.chr=>737,175.chr=>333, + 176.chr=>400,177.chr=>584,178.chr=>333,179.chr=>333,180.chr=>333,181.chr=>611,182.chr=>556,183.chr=>278,184.chr=>333,185.chr=>333,186.chr=>365,187.chr=>556,188.chr=>834,189.chr=>834,190.chr=>834,191.chr=>611,192.chr=>722,193.chr=>722,194.chr=>722,195.chr=>722,196.chr=>722,197.chr=>722, + 198.chr=>1000,199.chr=>722,200.chr=>667,201.chr=>667,202.chr=>667,203.chr=>667,204.chr=>278,205.chr=>278,206.chr=>278,207.chr=>278,208.chr=>722,209.chr=>722,210.chr=>778,211.chr=>778,212.chr=>778,213.chr=>778,214.chr=>778,215.chr=>584,216.chr=>778,217.chr=>722,218.chr=>722,219.chr=>722, + 220.chr=>722,221.chr=>667,222.chr=>667,223.chr=>611,224.chr=>556,225.chr=>556,226.chr=>556,227.chr=>556,228.chr=>556,229.chr=>556,230.chr=>889,231.chr=>556,232.chr=>556,233.chr=>556,234.chr=>556,235.chr=>556,236.chr=>278,237.chr=>278,238.chr=>278,239.chr=>278,240.chr=>611,241.chr=>611, + 242.chr=>611,243.chr=>611,244.chr=>611,245.chr=>611,246.chr=>611,247.chr=>584,248.chr=>611,249.chr=>611,250.chr=>611,251.chr=>611,252.chr=>611,253.chr=>556,254.chr=>611,255.chr=>556} +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/helveticabi.rb b/lib/plugins/rfpdf/lib/fonts/helveticabi.rb new file mode 100644 index 000000000..14fe4f80a --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/helveticabi.rb @@ -0,0 +1,15 @@ +TCPDFFontDescriptor.define('helveticabi') do |font| + font[:cw]={ + 0.chr=>278,1.chr=>278,2.chr=>278,3.chr=>278,4.chr=>278,5.chr=>278,6.chr=>278,7.chr=>278,8.chr=>278,9.chr=>278,10.chr=>278,11.chr=>278,12.chr=>278,13.chr=>278,14.chr=>278,15.chr=>278,16.chr=>278,17.chr=>278,18.chr=>278,19.chr=>278,20.chr=>278,21.chr=>278, + 22.chr=>278,23.chr=>278,24.chr=>278,25.chr=>278,26.chr=>278,27.chr=>278,28.chr=>278,29.chr=>278,30.chr=>278,31.chr=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, + 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889, + 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,127.chr=>350,128.chr=>556,129.chr=>350,130.chr=>278,131.chr=>556, + 132.chr=>500,133.chr=>1000,134.chr=>556,135.chr=>556,136.chr=>333,137.chr=>1000,138.chr=>667,139.chr=>333,140.chr=>1000,141.chr=>350,142.chr=>611,143.chr=>350,144.chr=>350,145.chr=>278,146.chr=>278,147.chr=>500,148.chr=>500,149.chr=>350,150.chr=>556,151.chr=>1000,152.chr=>333,153.chr=>1000, + 154.chr=>556,155.chr=>333,156.chr=>944,157.chr=>350,158.chr=>500,159.chr=>667,160.chr=>278,161.chr=>333,162.chr=>556,163.chr=>556,164.chr=>556,165.chr=>556,166.chr=>280,167.chr=>556,168.chr=>333,169.chr=>737,170.chr=>370,171.chr=>556,172.chr=>584,173.chr=>333,174.chr=>737,175.chr=>333, + 176.chr=>400,177.chr=>584,178.chr=>333,179.chr=>333,180.chr=>333,181.chr=>611,182.chr=>556,183.chr=>278,184.chr=>333,185.chr=>333,186.chr=>365,187.chr=>556,188.chr=>834,189.chr=>834,190.chr=>834,191.chr=>611,192.chr=>722,193.chr=>722,194.chr=>722,195.chr=>722,196.chr=>722,197.chr=>722, + 198.chr=>1000,199.chr=>722,200.chr=>667,201.chr=>667,202.chr=>667,203.chr=>667,204.chr=>278,205.chr=>278,206.chr=>278,207.chr=>278,208.chr=>722,209.chr=>722,210.chr=>778,211.chr=>778,212.chr=>778,213.chr=>778,214.chr=>778,215.chr=>584,216.chr=>778,217.chr=>722,218.chr=>722,219.chr=>722, + 220.chr=>722,221.chr=>667,222.chr=>667,223.chr=>611,224.chr=>556,225.chr=>556,226.chr=>556,227.chr=>556,228.chr=>556,229.chr=>556,230.chr=>889,231.chr=>556,232.chr=>556,233.chr=>556,234.chr=>556,235.chr=>556,236.chr=>278,237.chr=>278,238.chr=>278,239.chr=>278,240.chr=>611,241.chr=>611, + 242.chr=>611,243.chr=>611,244.chr=>611,245.chr=>611,246.chr=>611,247.chr=>584,248.chr=>611,249.chr=>611,250.chr=>611,251.chr=>611,252.chr=>611,253.chr=>556,254.chr=>611,255.chr=>556} +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/helveticai.rb b/lib/plugins/rfpdf/lib/fonts/helveticai.rb new file mode 100644 index 000000000..0158faf00 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/helveticai.rb @@ -0,0 +1,15 @@ +TCPDFFontDescriptor.define('helveticai') do |font| + font[:cw]={ + 0.chr=>278,1.chr=>278,2.chr=>278,3.chr=>278,4.chr=>278,5.chr=>278,6.chr=>278,7.chr=>278,8.chr=>278,9.chr=>278,10.chr=>278,11.chr=>278,12.chr=>278,13.chr=>278,14.chr=>278,15.chr=>278,16.chr=>278,17.chr=>278,18.chr=>278,19.chr=>278,20.chr=>278,21.chr=>278, + 22.chr=>278,23.chr=>278,24.chr=>278,25.chr=>278,26.chr=>278,27.chr=>278,28.chr=>278,29.chr=>278,30.chr=>278,31.chr=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667, + 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833, + 'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,127.chr=>350,128.chr=>556,129.chr=>350,130.chr=>222,131.chr=>556, + 132.chr=>333,133.chr=>1000,134.chr=>556,135.chr=>556,136.chr=>333,137.chr=>1000,138.chr=>667,139.chr=>333,140.chr=>1000,141.chr=>350,142.chr=>611,143.chr=>350,144.chr=>350,145.chr=>222,146.chr=>222,147.chr=>333,148.chr=>333,149.chr=>350,150.chr=>556,151.chr=>1000,152.chr=>333,153.chr=>1000, + 154.chr=>500,155.chr=>333,156.chr=>944,157.chr=>350,158.chr=>500,159.chr=>667,160.chr=>278,161.chr=>333,162.chr=>556,163.chr=>556,164.chr=>556,165.chr=>556,166.chr=>260,167.chr=>556,168.chr=>333,169.chr=>737,170.chr=>370,171.chr=>556,172.chr=>584,173.chr=>333,174.chr=>737,175.chr=>333, + 176.chr=>400,177.chr=>584,178.chr=>333,179.chr=>333,180.chr=>333,181.chr=>556,182.chr=>537,183.chr=>278,184.chr=>333,185.chr=>333,186.chr=>365,187.chr=>556,188.chr=>834,189.chr=>834,190.chr=>834,191.chr=>611,192.chr=>667,193.chr=>667,194.chr=>667,195.chr=>667,196.chr=>667,197.chr=>667, + 198.chr=>1000,199.chr=>722,200.chr=>667,201.chr=>667,202.chr=>667,203.chr=>667,204.chr=>278,205.chr=>278,206.chr=>278,207.chr=>278,208.chr=>722,209.chr=>722,210.chr=>778,211.chr=>778,212.chr=>778,213.chr=>778,214.chr=>778,215.chr=>584,216.chr=>778,217.chr=>722,218.chr=>722,219.chr=>722, + 220.chr=>722,221.chr=>667,222.chr=>667,223.chr=>611,224.chr=>556,225.chr=>556,226.chr=>556,227.chr=>556,228.chr=>556,229.chr=>556,230.chr=>889,231.chr=>500,232.chr=>556,233.chr=>556,234.chr=>556,235.chr=>556,236.chr=>278,237.chr=>278,238.chr=>278,239.chr=>278,240.chr=>556,241.chr=>556, + 242.chr=>556,243.chr=>556,244.chr=>556,245.chr=>556,246.chr=>556,247.chr=>584,248.chr=>611,249.chr=>556,250.chr=>556,251.chr=>556,252.chr=>556,253.chr=>500,254.chr=>556,255.chr=>500} +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/old/.noencode b/lib/plugins/rfpdf/lib/fonts/old/.noencode new file mode 100644 index 000000000..e69de29bb diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1250.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1250.map new file mode 100644 index 000000000..ec110af06 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1250.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+015A Sacute +!8D U+0164 Tcaron +!8E U+017D Zcaron +!8F U+0179 Zacute +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+015B sacute +!9D U+0165 tcaron +!9E U+017E zcaron +!9F U+017A zacute +!A0 U+00A0 space +!A1 U+02C7 caron +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+0104 Aogonek +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+015E Scedilla +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+0105 aogonek +!BA U+015F scedilla +!BB U+00BB guillemotright +!BC U+013D Lcaron +!BD U+02DD hungarumlaut +!BE U+013E lcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1251.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1251.map new file mode 100644 index 000000000..de6a198d9 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1251.map @@ -0,0 +1,255 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0402 afii10051 +!81 U+0403 afii10052 +!82 U+201A quotesinglbase +!83 U+0453 afii10100 +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+20AC Euro +!89 U+2030 perthousand +!8A U+0409 afii10058 +!8B U+2039 guilsinglleft +!8C U+040A afii10059 +!8D U+040C afii10061 +!8E U+040B afii10060 +!8F U+040F afii10145 +!90 U+0452 afii10099 +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0459 afii10106 +!9B U+203A guilsinglright +!9C U+045A afii10107 +!9D U+045C afii10109 +!9E U+045B afii10108 +!9F U+045F afii10193 +!A0 U+00A0 space +!A1 U+040E afii10062 +!A2 U+045E afii10110 +!A3 U+0408 afii10057 +!A4 U+00A4 currency +!A5 U+0490 afii10050 +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+0401 afii10023 +!A9 U+00A9 copyright +!AA U+0404 afii10053 +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+0407 afii10056 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+0406 afii10055 +!B3 U+0456 afii10103 +!B4 U+0491 afii10098 +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0451 afii10071 +!B9 U+2116 afii61352 +!BA U+0454 afii10101 +!BB U+00BB guillemotright +!BC U+0458 afii10105 +!BD U+0405 afii10054 +!BE U+0455 afii10102 +!BF U+0457 afii10104 +!C0 U+0410 afii10017 +!C1 U+0411 afii10018 +!C2 U+0412 afii10019 +!C3 U+0413 afii10020 +!C4 U+0414 afii10021 +!C5 U+0415 afii10022 +!C6 U+0416 afii10024 +!C7 U+0417 afii10025 +!C8 U+0418 afii10026 +!C9 U+0419 afii10027 +!CA U+041A afii10028 +!CB U+041B afii10029 +!CC U+041C afii10030 +!CD U+041D afii10031 +!CE U+041E afii10032 +!CF U+041F afii10033 +!D0 U+0420 afii10034 +!D1 U+0421 afii10035 +!D2 U+0422 afii10036 +!D3 U+0423 afii10037 +!D4 U+0424 afii10038 +!D5 U+0425 afii10039 +!D6 U+0426 afii10040 +!D7 U+0427 afii10041 +!D8 U+0428 afii10042 +!D9 U+0429 afii10043 +!DA U+042A afii10044 +!DB U+042B afii10045 +!DC U+042C afii10046 +!DD U+042D afii10047 +!DE U+042E afii10048 +!DF U+042F afii10049 +!E0 U+0430 afii10065 +!E1 U+0431 afii10066 +!E2 U+0432 afii10067 +!E3 U+0433 afii10068 +!E4 U+0434 afii10069 +!E5 U+0435 afii10070 +!E6 U+0436 afii10072 +!E7 U+0437 afii10073 +!E8 U+0438 afii10074 +!E9 U+0439 afii10075 +!EA U+043A afii10076 +!EB U+043B afii10077 +!EC U+043C afii10078 +!ED U+043D afii10079 +!EE U+043E afii10080 +!EF U+043F afii10081 +!F0 U+0440 afii10082 +!F1 U+0441 afii10083 +!F2 U+0442 afii10084 +!F3 U+0443 afii10085 +!F4 U+0444 afii10086 +!F5 U+0445 afii10087 +!F6 U+0446 afii10088 +!F7 U+0447 afii10089 +!F8 U+0448 afii10090 +!F9 U+0449 afii10091 +!FA U+044A afii10092 +!FB U+044B afii10093 +!FC U+044C afii10094 +!FD U+044D afii10095 +!FE U+044E afii10096 +!FF U+044F afii10097 diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1252.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1252.map new file mode 100644 index 000000000..dd490e596 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1252.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!8E U+017D Zcaron +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9E U+017E zcaron +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1253.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1253.map new file mode 100644 index 000000000..4bd826fb2 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1253.map @@ -0,0 +1,239 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+0385 dieresistonos +!A2 U+0386 Alphatonos +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1254.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1254.map new file mode 100644 index 000000000..829473b28 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1254.map @@ -0,0 +1,249 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1255.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1255.map new file mode 100644 index 000000000..079e10c61 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1255.map @@ -0,0 +1,233 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AA afii57636 +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00D7 multiply +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD sfthyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 middot +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00F7 divide +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+05B0 afii57799 +!C1 U+05B1 afii57801 +!C2 U+05B2 afii57800 +!C3 U+05B3 afii57802 +!C4 U+05B4 afii57793 +!C5 U+05B5 afii57794 +!C6 U+05B6 afii57795 +!C7 U+05B7 afii57798 +!C8 U+05B8 afii57797 +!C9 U+05B9 afii57806 +!CB U+05BB afii57796 +!CC U+05BC afii57807 +!CD U+05BD afii57839 +!CE U+05BE afii57645 +!CF U+05BF afii57841 +!D0 U+05C0 afii57842 +!D1 U+05C1 afii57804 +!D2 U+05C2 afii57803 +!D3 U+05C3 afii57658 +!D4 U+05F0 afii57716 +!D5 U+05F1 afii57717 +!D6 U+05F2 afii57718 +!D7 U+05F3 gereshhebrew +!D8 U+05F4 gershayimhebrew +!E0 U+05D0 afii57664 +!E1 U+05D1 afii57665 +!E2 U+05D2 afii57666 +!E3 U+05D3 afii57667 +!E4 U+05D4 afii57668 +!E5 U+05D5 afii57669 +!E6 U+05D6 afii57670 +!E7 U+05D7 afii57671 +!E8 U+05D8 afii57672 +!E9 U+05D9 afii57673 +!EA U+05DA afii57674 +!EB U+05DB afii57675 +!EC U+05DC afii57676 +!ED U+05DD afii57677 +!EE U+05DE afii57678 +!EF U+05DF afii57679 +!F0 U+05E0 afii57680 +!F1 U+05E1 afii57681 +!F2 U+05E2 afii57682 +!F3 U+05E3 afii57683 +!F4 U+05E4 afii57684 +!F5 U+05E5 afii57685 +!F6 U+05E6 afii57686 +!F7 U+05E7 afii57687 +!F8 U+05E8 afii57688 +!F9 U+05E9 afii57689 +!FA U+05EA afii57690 +!FD U+200E afii299 +!FE U+200F afii300 diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1257.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1257.map new file mode 100644 index 000000000..2f2ecfa21 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1257.map @@ -0,0 +1,244 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8D U+00A8 dieresis +!8E U+02C7 caron +!8F U+00B8 cedilla +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!9D U+00AF macron +!9E U+02DB ogonek +!A0 U+00A0 space +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00D8 Oslash +!A9 U+00A9 copyright +!AA U+0156 Rcommaaccent +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00C6 AE +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00F8 oslash +!B9 U+00B9 onesuperior +!BA U+0157 rcommaaccent +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00E6 ae +!C0 U+0104 Aogonek +!C1 U+012E Iogonek +!C2 U+0100 Amacron +!C3 U+0106 Cacute +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+0118 Eogonek +!C7 U+0112 Emacron +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0179 Zacute +!CB U+0116 Edotaccent +!CC U+0122 Gcommaaccent +!CD U+0136 Kcommaaccent +!CE U+012A Imacron +!CF U+013B Lcommaaccent +!D0 U+0160 Scaron +!D1 U+0143 Nacute +!D2 U+0145 Ncommaaccent +!D3 U+00D3 Oacute +!D4 U+014C Omacron +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0172 Uogonek +!D9 U+0141 Lslash +!DA U+015A Sacute +!DB U+016A Umacron +!DC U+00DC Udieresis +!DD U+017B Zdotaccent +!DE U+017D Zcaron +!DF U+00DF germandbls +!E0 U+0105 aogonek +!E1 U+012F iogonek +!E2 U+0101 amacron +!E3 U+0107 cacute +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+0119 eogonek +!E7 U+0113 emacron +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+017A zacute +!EB U+0117 edotaccent +!EC U+0123 gcommaaccent +!ED U+0137 kcommaaccent +!EE U+012B imacron +!EF U+013C lcommaaccent +!F0 U+0161 scaron +!F1 U+0144 nacute +!F2 U+0146 ncommaaccent +!F3 U+00F3 oacute +!F4 U+014D omacron +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0173 uogonek +!F9 U+0142 lslash +!FA U+015B sacute +!FB U+016B umacron +!FC U+00FC udieresis +!FD U+017C zdotaccent +!FE U+017E zcaron +!FF U+02D9 dotaccent diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1258.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1258.map new file mode 100644 index 000000000..fed915f71 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp1258.map @@ -0,0 +1,247 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+0300 gravecomb +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+00D1 Ntilde +!D2 U+0309 hookabovecomb +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+01A0 Ohorn +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+01AF Uhorn +!DE U+0303 tildecomb +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+0301 acutecomb +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+00F1 ntilde +!F2 U+0323 dotbelowcomb +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+01A1 ohorn +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+01B0 uhorn +!FE U+20AB dong +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/cp874.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp874.map new file mode 100644 index 000000000..1006e6b17 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/cp874.map @@ -0,0 +1,225 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!85 U+2026 ellipsis +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-1.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-1.map new file mode 100644 index 000000000..61740a38f --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-1.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-11.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-11.map new file mode 100644 index 000000000..916881206 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-11.map @@ -0,0 +1,248 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-15.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-15.map new file mode 100644 index 000000000..6c2b57127 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-15.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AC Euro +!A5 U+00A5 yen +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+017D Zcaron +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-16.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-16.map new file mode 100644 index 000000000..202c8fe59 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-16.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0105 aogonek +!A3 U+0141 Lslash +!A4 U+20AC Euro +!A5 U+201E quotedblbase +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+0218 Scommaaccent +!AB U+00AB guillemotleft +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017A zacute +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+010C Ccaron +!B3 U+0142 lslash +!B4 U+017D Zcaron +!B5 U+201D quotedblright +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+010D ccaron +!BA U+0219 scommaaccent +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+017C zdotaccent +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0106 Cacute +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+015A Sacute +!D8 U+0170 Uhungarumlaut +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0118 Eogonek +!DE U+021A Tcommaaccent +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+0107 cacute +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+015B sacute +!F8 U+0171 uhungarumlaut +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0119 eogonek +!FE U+021B tcommaaccent +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-2.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-2.map new file mode 100644 index 000000000..65ae09f95 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-2.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+013D Lcaron +!A6 U+015A Sacute +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+015E Scedilla +!AB U+0164 Tcaron +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+013E lcaron +!B6 U+015B sacute +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+015F scedilla +!BB U+0165 tcaron +!BC U+017A zacute +!BD U+02DD hungarumlaut +!BE U+017E zcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-4.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-4.map new file mode 100644 index 000000000..a7d87bf3e --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-4.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0138 kgreenlandic +!A3 U+0156 Rcommaaccent +!A4 U+00A4 currency +!A5 U+0128 Itilde +!A6 U+013B Lcommaaccent +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+0112 Emacron +!AB U+0122 Gcommaaccent +!AC U+0166 Tbar +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0157 rcommaaccent +!B4 U+00B4 acute +!B5 U+0129 itilde +!B6 U+013C lcommaaccent +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+0113 emacron +!BB U+0123 gcommaaccent +!BC U+0167 tbar +!BD U+014A Eng +!BE U+017E zcaron +!BF U+014B eng +!C0 U+0100 Amacron +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+012E Iogonek +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+0116 Edotaccent +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+012A Imacron +!D0 U+0110 Dcroat +!D1 U+0145 Ncommaaccent +!D2 U+014C Omacron +!D3 U+0136 Kcommaaccent +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+0172 Uogonek +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0168 Utilde +!DE U+016A Umacron +!DF U+00DF germandbls +!E0 U+0101 amacron +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+012F iogonek +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+0117 edotaccent +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+012B imacron +!F0 U+0111 dcroat +!F1 U+0146 ncommaaccent +!F2 U+014D omacron +!F3 U+0137 kcommaaccent +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+0173 uogonek +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0169 utilde +!FE U+016B umacron +!FF U+02D9 dotaccent diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-5.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-5.map new file mode 100644 index 000000000..f9cd4edcf --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-5.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0401 afii10023 +!A2 U+0402 afii10051 +!A3 U+0403 afii10052 +!A4 U+0404 afii10053 +!A5 U+0405 afii10054 +!A6 U+0406 afii10055 +!A7 U+0407 afii10056 +!A8 U+0408 afii10057 +!A9 U+0409 afii10058 +!AA U+040A afii10059 +!AB U+040B afii10060 +!AC U+040C afii10061 +!AD U+00AD hyphen +!AE U+040E afii10062 +!AF U+040F afii10145 +!B0 U+0410 afii10017 +!B1 U+0411 afii10018 +!B2 U+0412 afii10019 +!B3 U+0413 afii10020 +!B4 U+0414 afii10021 +!B5 U+0415 afii10022 +!B6 U+0416 afii10024 +!B7 U+0417 afii10025 +!B8 U+0418 afii10026 +!B9 U+0419 afii10027 +!BA U+041A afii10028 +!BB U+041B afii10029 +!BC U+041C afii10030 +!BD U+041D afii10031 +!BE U+041E afii10032 +!BF U+041F afii10033 +!C0 U+0420 afii10034 +!C1 U+0421 afii10035 +!C2 U+0422 afii10036 +!C3 U+0423 afii10037 +!C4 U+0424 afii10038 +!C5 U+0425 afii10039 +!C6 U+0426 afii10040 +!C7 U+0427 afii10041 +!C8 U+0428 afii10042 +!C9 U+0429 afii10043 +!CA U+042A afii10044 +!CB U+042B afii10045 +!CC U+042C afii10046 +!CD U+042D afii10047 +!CE U+042E afii10048 +!CF U+042F afii10049 +!D0 U+0430 afii10065 +!D1 U+0431 afii10066 +!D2 U+0432 afii10067 +!D3 U+0433 afii10068 +!D4 U+0434 afii10069 +!D5 U+0435 afii10070 +!D6 U+0436 afii10072 +!D7 U+0437 afii10073 +!D8 U+0438 afii10074 +!D9 U+0439 afii10075 +!DA U+043A afii10076 +!DB U+043B afii10077 +!DC U+043C afii10078 +!DD U+043D afii10079 +!DE U+043E afii10080 +!DF U+043F afii10081 +!E0 U+0440 afii10082 +!E1 U+0441 afii10083 +!E2 U+0442 afii10084 +!E3 U+0443 afii10085 +!E4 U+0444 afii10086 +!E5 U+0445 afii10087 +!E6 U+0446 afii10088 +!E7 U+0447 afii10089 +!E8 U+0448 afii10090 +!E9 U+0449 afii10091 +!EA U+044A afii10092 +!EB U+044B afii10093 +!EC U+044C afii10094 +!ED U+044D afii10095 +!EE U+044E afii10096 +!EF U+044F afii10097 +!F0 U+2116 afii61352 +!F1 U+0451 afii10071 +!F2 U+0452 afii10099 +!F3 U+0453 afii10100 +!F4 U+0454 afii10101 +!F5 U+0455 afii10102 +!F6 U+0456 afii10103 +!F7 U+0457 afii10104 +!F8 U+0458 afii10105 +!F9 U+0459 afii10106 +!FA U+045A afii10107 +!FB U+045B afii10108 +!FC U+045C afii10109 +!FD U+00A7 section +!FE U+045E afii10110 +!FF U+045F afii10193 diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-7.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-7.map new file mode 100644 index 000000000..e163796b1 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-7.map @@ -0,0 +1,250 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+2018 quoteleft +!A2 U+2019 quoteright +!A3 U+00A3 sterling +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+0385 dieresistonos +!B6 U+0386 Alphatonos +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-9.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-9.map new file mode 100644 index 000000000..48c123ae6 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/iso-8859-9.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-r.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-r.map new file mode 100644 index 000000000..6ad5d05d0 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-r.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2219 periodcentered +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+2553 SF520000 +!A5 U+2554 SF390000 +!A6 U+2555 SF220000 +!A7 U+2556 SF210000 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+255C SF270000 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+2562 SF200000 +!B5 U+2563 SF230000 +!B6 U+2564 SF470000 +!B7 U+2565 SF480000 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+256B SF530000 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-u.map b/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-u.map new file mode 100644 index 000000000..40a7e4fd7 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/koi8-u.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2022 bullet +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+0454 afii10101 +!A5 U+2554 SF390000 +!A6 U+0456 afii10103 +!A7 U+0457 afii10104 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+0491 afii10098 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+0404 afii10053 +!B5 U+2563 SF230000 +!B6 U+0406 afii10055 +!B7 U+0407 afii10056 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+0490 afii10050 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/lib/plugins/rfpdf/lib/fonts/old/makefont/makefont.php b/lib/plugins/rfpdf/lib/fonts/old/makefont/makefont.php new file mode 100644 index 000000000..cff86923d --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/old/makefont/makefont.php @@ -0,0 +1,411 @@ + +#***************************************************************************** +# Utility to generate font definition files # +# Version: 1.13 # +# Date: 2004-12-31 # +******************************************************************************# + +function ReadMap($enc) +{ + #Read a map file + $file=dirname(__FILE__) + '/' + $enc.downcase + '.map'; + $a=file($file); + if ($a)) + die('Error: encoding not found: '.$enc); + $cc2gn = [] + foreach($a as $l) + { + if ($l{0}=='!') + { + $e=rtrim($l).scan('/[ \\t]+/'); + $cc=hexdec(substr($e[0],1)); + $gn=$e[2]; + $cc2gn[$cc]=$gn; + end + end + for($i=0;$i<=255;$i++) + { + if (!$cc2gn[$i].nil?) + $cc2gn[$i]='.notdef'; + end + return $cc2gn; +} + +function ReadAFM($file,&$map) +{ + #Read a font metric file + $a=file($file); + if ($a.empty?) + die('File not found'); + $widths = [] + $fm = [] + $fix=Hash.new('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent', + 'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut', + 'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent', + 'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent', + 'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent', + 'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat', + 'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb', + 'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong'); + foreach($a as $l) + { + $e=explode(' ',rtrim($l)); + if ($e.length<2) + continue; + $code=$e[0]; + $param=$e[1]; + if ($code=='C') + { + #Character metrics + $cc=(int)$e[1]; + $w=$e[4]; + $gn=$e[7]; + if (substr($gn,-4)=='20AC') + $gn='Euro'; + if ($fix[$gn].nil?) + { + #Fix incorrect glyph name + foreach($map as $c=>$n) + { + if ($n==$fix[$gn]) + $map[$c]=$gn; + end + end + if ($map.empty?) + { + #Symbolic font: use built-in encoding + $widths[$cc]=$w; + else + { + $widths[$gn]=$w; + if ($gn=='X') + $fm['CapXHeight']=$e[13]; + end + if ($gn=='.notdef') + $fm['MissingWidth']=$w; + elsif ($code=='FontName') + $fm['FontName']=$param; + elsif ($code=='Weight') + $fm['Weight']=$param; + elsif ($code=='ItalicAngle') + $fm['ItalicAngle']=(double)$param; + elsif ($code=='Ascender') + $fm['Ascender']=(int)$param; + elsif ($code=='Descender') + $fm['Descender']=(int)$param; + elsif ($code=='UnderlineThickness') + $fm['UnderlineThickness']=(int)$param; + elsif ($code=='UnderlinePosition') + $fm['UnderlinePosition']=(int)$param; + elsif ($code=='IsFixedPitch') + $fm['IsFixedPitch']=($param=='true'); + elsif ($code=='FontBBox') + $fm['FontBBox']=Hash.new($e[1],$e[2],$e[3],$e[4]); + elsif ($code=='CapHeight') + $fm['CapHeight']=(int)$param; + elsif ($code=='StdVW') + $fm['StdVW']=(int)$param; + end + if (!$fm['FontName'].nil?) + die('FontName not found'); + if (!$map.empty?) + { + if (!$widths['.notdef'].nil?) + $widths['.notdef']=600; + if (!$widths['Delta'].nil? and $widths['increment'].nil?) + $widths['Delta']=$widths['increment']; + #Order widths according to map + for($i=0;$i<=255;$i++) + { + if (!$widths[$map[$i]].nil?) + { + echo 'Warning: character '.$map[$i].' is missing
    '; + $widths[$i]=$widths['.notdef']; + else + $widths[$i]=$widths[$map[$i]]; + end + end + $fm['Widths']=$widths; + return $fm; +} + +function MakeFontDescriptor($fm,$symbolic) +{ + #Ascent + $asc=($fm['Ascender'].nil? ? $fm['Ascender'] : 1000); + $fd="Hash.new('Ascent'=>".$asc; + #Descent + $desc=($fm['Descender'].nil? ? $fm['Descender'] : -200); + $fd<<",'Descent'=>".$desc; + #CapHeight + if ($fm['CapHeight'].nil?) + $ch=$fm['CapHeight']; + elsif ($fm['CapXHeight'].nil?) + $ch=$fm['CapXHeight']; + else + $ch=$asc; + $fd<<",'CapHeight'=>".$ch; + #Flags + $flags=0; + if ($fm['IsFixedPitch'].nil? and $fm['IsFixedPitch']) + $flags+=1<<0; + if ($symbolic) + $flags+=1<<2; + if (!$symbolic) + $flags+=1<<5; + if ($fm['ItalicAngle'].nil? and $fm['ItalicAngle']!=0) + $flags+=1<<6; + $fd<<",'Flags'=>".$flags; + #FontBBox + if ($fm['FontBBox'].nil?) + $fbb=$fm['FontBBox']; + else + $fbb=Hash.new(0,$des-100,1000,$asc+100); + $fd<<",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'"; + #ItalicAngle + $ia=($fm['ItalicAngle'].nil? ? $fm['ItalicAngle'] : 0); + $fd<<",'ItalicAngle'=>".$ia; + #StemV + if ($fm['StdVW'].nil?) + $stemv=$fm['StdVW']; + elsif ($fm['Weight'].nil? and eregi('(bold|black)',$fm['Weight'])) + $stemv=120; + else + $stemv=70; + $fd<<",'StemV'=>".$stemv; + #MissingWidth + if ($fm['MissingWidth'].nil?) + $fd<<",'MissingWidth'=>".$fm['MissingWidth']; + $fd<<')'; + return $fd; +} + +function MakeWidthArray($fm) +{ + #Make character width array + $s="Hash.new(\n\t"; + $cw=$fm['Widths']; + for($i=0;$i<=255;$i++) + { + if ($i.chr=="'") + $s<<"'\\''"; + elsif ($i.chr=="\\") + $s<<"'\\\\'"; + elsif ($i>=32 and $i<=126) + $s<<"'".$i.chr."'"; + else + $s<<"$i.chr"; + $s<<'=>'.$fm['Widths'][$i]; + if ($i<255) + $s<<','; + if (($i+1)%22==0) + $s<<"\n\t"; + end + $s<<')'; + return $s; +} + +function MakeFontEncoding($map) +{ + #Build differences from reference encoding + $ref=ReadMap('cp1252'); + $s=''; + $last=0; + for($i=32;$i<=255;$i++) + { + if ($map[$i]!=$ref[$i]) + { + if ($i!=$last+1) + $s<<$i.' '; + $last=$i; + $s<<'/'.$map[$i].' '; + end + end + return rtrim($s); +} + +function SaveToFile($file,$s,$mode='t') +{ + $f=fopen($file,'w'.$mode); + if (!$f) + die('Can\'t write to file '.$file); + fwrite($f,$s,$s.length); + fclose($f); +} + +function ReadShort($f) +{ + $a=unpack('n1n',fread($f,2)); + return $a['n']; +} + +function ReadLong($f) +{ + $a=unpack('N1N',fread($f,4)); + return $a['N']; +} + +function CheckTTF($file) +{ + #Check if font license allows embedding + $f=fopen($file,'rb'); + if (!$f) + die('Error: Can\'t open '.$file); + #Extract number of tables + fseek($f,4,SEEK_CUR); + $nb=ReadShort($f); + fseek($f,6,SEEK_CUR); + #Seek OS/2 table + $found=false; + for($i=0;$i<$nb;$i++) + { + if (fread($f,4)=='OS/2') + { + $found=true; + break; + end + fseek($f,12,SEEK_CUR); + end + if (!$found) + { + fclose($f); + return; + end + fseek($f,4,SEEK_CUR); + $offset=ReadLong($f); + fseek($f,$offset,SEEK_SET); + #Extract fsType flags + fseek($f,8,SEEK_CUR); + $fsType=ReadShort($f); + $rl=($fsType & 0x02)!=0; + $pp=($fsType & 0x04)!=0; + $e=($fsType & 0x08)!=0; + fclose($f); + if ($rl and !$pp and !$e) + echo 'Warning: font license does not allow embedding'; +} + +#***************************************************************************** +# $fontfile : chemin du fichier TTF (ou chaîne vide si pas d'incorporation) # +# $afmfile : chemin du fichier AFM # +# $enc : encodage (ou chaîne vide si la police est symbolique) # +# $patch : patch optionnel pour l'encodage # +# $type : type de la police si $fontfile est vide # +******************************************************************************# +function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=Hash.new(),$type='TrueType') +{ + #Generate a font definition file + set_magic_quotes_runtime(0); + ini_set('auto_detect_line_endings','1'); + if ($enc) + { + $map=ReadMap($enc); + foreach($patch as $cc=>$gn) + $map[$cc]=$gn; + end + else + $map = [] + if (!file_exists($afmfile)) + die('Error: AFM file not found: '.$afmfile); + $fm=ReadAFM($afmfile,$map); + if ($enc) + $diff=MakeFontEncoding($map); + else + $diff=''; + $fd=MakeFontDescriptor($fm,$map.empty?); + #Find font type + if ($fontfile) + { + $ext=strtolower(substr($fontfile,-3)); + if ($ext=='ttf') + $type='TrueType'; + elsif ($ext=='pfb') + $type='Type1'; + else + die('Error: unrecognized font file extension: '.$ext); + end + else + { + if ($type!='TrueType' and $type!='Type1') + die('Error: incorrect font type: '.$type); + end + #Start generation + $s=''."\n"; + $s<<'$type=\''.$type."';\n"; + $s<<'$name=\''.$fm['FontName']."';\n"; + $s<<'$desc='.$fd.";\n"; + if (!$fm['UnderlinePosition'].nil?) + $fm['UnderlinePosition']=-100; + if (!$fm['UnderlineThickness'].nil?) + $fm['UnderlineThickness']=50; + $s<<'$up='.$fm['UnderlinePosition'].";\n"; + $s<<'$ut='.$fm['UnderlineThickness'].";\n"; + $w=MakeWidthArray($fm); + $s<<'$cw='.$w.";\n"; + $s<<'$enc=\''.$enc."';\n"; + $s<<'$diff=\''.$diff."';\n"; + $basename=substr(basename($afmfile),0,-4); + if ($fontfile) + { + #Embedded font + if (!file_exists($fontfile)) + die('Error: font file not found: '.$fontfile); + if ($type=='TrueType') + CheckTTF($fontfile); + $f=fopen($fontfile,'rb'); + if (!$f) + die('Error: Can\'t open '.$fontfile); + $file=fread($f,filesize($fontfile)); + fclose($f); + if ($type=='Type1') + { + #Find first two sections and discard third one + $header=($file[0][0]==128); + if ($header) + { + #Strip first binary header + $file=substr($file,6); + end + $pos=$file.include?('eexec'); + if (!$pos) + die('Error: font file does not seem to be valid Type1'); + $size1=$pos+6; + if ($header and ?($file{$size1})==128) + { + #Strip second binary header + $file=substr($file,0,$size1).substr($file,$size1+6); + end + $pos=$file.include?('00000000'); + if (!$pos) + die('Error: font file does not seem to be valid Type1'); + $size2=$pos-$size1; + $file=substr($file,0,$size1+$size2); + end + if (respond_to('gzcompress')) + { + $cmp=$basename.'.z'; + SaveToFile($cmp,gzcompress($file),'b'); + $s<<'$file=\''.$cmp."';\n"; + echo 'Font file compressed ('.$cmp.')
    '; + else + { + $s<<'$file=\''.basename($fontfile)."';\n"; + echo 'Notice: font file could not be compressed (zlib extension not available)
    '; + end + if ($type=='Type1') + { + $s<<'$size1='.$size1.";\n"; + $s<<'$size2='.$size2.";\n"; + else + $s<<'$originalsize='.filesize($fontfile).";\n"; + end + else + { + #Not embedded font + $s<<'$file='."'';\n"; + end + $s<<"\n"; + SaveToFile($basename.'.rb',$s); + echo 'Font definition file generated ('.$basename.'.rb'.')
    '; +} + diff --git a/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT new file mode 100644 index 000000000..e6741f7c0 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT @@ -0,0 +1,124 @@ +Bitstream Vera Fonts Copyright + +The fonts have a generous copyright, allowing derivative works (as +long as "Bitstream" or "Vera" are not in the names), and full +redistribution (so long as they are not#sold# by themselves). They +can be be bundled, redistributed and sold with any software. + +The fonts are distributed under the following copyright: + +Copyright +========= + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream +Vera is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute +the Font Software, including without limitation the rights to use, +copy, merge, publish, distribute, and/or sell copies of the Font +Software, and to permit persons to whom the Font Software is furnished +to do so, subject to the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Bitstream" or the word "Vera". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Bitstream Vera" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT +SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font +Software without prior written authorization from the Gnome Foundation +or Bitstream Inc., respectively. For further information, contact: +fonts at gnome dot org. + +Copyright FAQ +============= + + 1. I don't understand the resale restriction... What gives? + + Bitstream is giving away these fonts, but wishes to ensure its + competitors can't just drop the fonts as is into a font sale system + and sell them as is. It seems fair that if Bitstream can't make money + from the Bitstream Vera fonts, their competitors should not be able to + do so either. You can sell the fonts as part of any software package, + however. + + 2. I want to package these fonts separately for distribution and + sale as part of a larger software package or system. Can I do so? + + Yes. A RPM or Debian package is a "larger software package" to begin + with, and you aren't selling them independently by themselves. + See 1. above. + + 3. Are derivative works allowed? + Yes! + + 4. Can I change or add to the font(s)? + Yes, but you must change the name(s) of the font(s). + + 5. Under what terms are derivative works allowed? + + You must change the name(s) of the fonts. This is to ensure the + quality of the fonts, both to protect Bitstream and Gnome. We want to + ensure that if an application has opened a font specifically of these + names, it gets what it expects (though of course, using fontconfig, + substitutions could still could have occurred during font + opening). You must include the Bitstream copyright. Additional + copyrights can be added, as per copyright law. Happy Font Hacking! + + 6. If I have improvements for Bitstream Vera, is it possible they might get + adopted in future versions? + + Yes. The contract between the Gnome Foundation and Bitstream has + provisions for working with Bitstream to ensure quality additions to + the Bitstream Vera font family. Please contact us if you have such + additions. Note, that in general, we will want such additions for the + entire family, not just a single font, and that you'll have to keep + both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add + glyphs to the font, they must be stylistically in keeping with Vera's + design. Vera cannot become a "ransom note" font. Jim Lyles will be + providing a document describing the design elements used in Vera, as a + guide and aid for people interested in contributing to Vera. + + 7. I want to sell a software package that uses these fonts: Can I do so? + + Sure. Bundle the fonts with your software and sell your software + with the fonts. That is the intent of the copyright. + + 8. If applications have built the names "Bitstream Vera" into them, + can I override this somehow to use fonts of my choosing? + + This depends on exact details of the software. Most open source + systems and software (e.g., Gnome, KDE, etc.) are now converting to + use fontconfig (see www.fontconfig.org) to handle font configuration, + selection and substitution; it has provisions for overriding font + names and subsituting alternatives. An example is provided by the + supplied local.conf file, which chooses the family Bitstream Vera for + "sans", "serif" and "monospace". Other software (e.g., the XFree86 + core server) has other mechanisms for font substitution. + diff --git a/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/README.TXT b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/README.TXT new file mode 100644 index 000000000..0f71795a7 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/README.TXT @@ -0,0 +1,11 @@ +Contained herin is the Bitstream Vera font family. + +The Copyright information is found in the COPYRIGHT.TXT file (along +with being incoporated into the fonts themselves). + +The releases notes are found in the file "RELEASENOTES.TXT". + +We hope you enjoy Vera! + + Bitstream, Inc. + The Gnome Project diff --git a/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT new file mode 100644 index 000000000..d9167e1e0 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT @@ -0,0 +1,162 @@ +Bitstream Vera Fonts - April 16, 2003 +===================================== + +The version number of these fonts is 1.10 to distinguish them from the +beta test fonts. + +Note that the Vera copyright is incorporated in the fonts themselves. +The License field in the fonts contains the copyright license as it +appears below. The TrueType copyright field is not large enough to +contain the full license, so the license is incorporated (as you might +think if you thought about it) into the license field, which +unfortunately can be obscure to find. (In pfaedit, see: Element->Font +Info->TTFNames->License). + +Our apologies for it taking longer to complete the fonts than planned. +Beta testers requested a tighter line spacing (less leading) and Jim +Lyles redesigned Vera's accents to bring its line spacing to more +typical of other fonts. This took additional time and effort. Our +thanks to Jim for this effort above and beyond the call of duty. + +There are four monospace and sans faces (normal, oblique, bold, bold +oblique) and two serif faces (normal and bold). Fontconfig/Xft2 (see +www.fontconfig.org) can artificially oblique the serif faces for you: +this loses hinting and distorts the faces slightly, but is visibly +different than normal and bold, and reasonably pleasing. + +On systems with fontconfig 2.0 or 2.1 installed, making your sans, +serif and monospace fonts default to these fonts is very easy. Just +drop the file local.conf into your /etc/fonts directory. This will +make the Bitstream fonts your default fonts for all applications using +fontconfig (if sans, serif, or monospace names are used, as they often +are as default values in many desktops). The XML in local.conf may +need modification to enable subpixel decimation, if appropriate, +however, the commented out phrase does so for XFree86 4.3, in the case +that the server does not have sufficient information to identify the +use of a flat panel. Fontconfig 2.2 adds Vera to the list of font +families and will, by default use it as the default sans, serif and +monospace fonts. + +During the testing of the final Vera fonts, we learned that screen +fonts in general are only typically hinted to work correctly at +integer pixel sizes. Vera is coded internally for integer sizes only. +We need to investigate further to see if there are commonly used fonts +that are hinted to be rounded but are not rounded to integer sizes due +to oversights in their coding. + +Most fonts work best at 8 pixels and below if anti-aliased only, as +the amount of work required to hint well at smaller and smaller sizes +becomes astronomical. GASP tables are typically used to control +whether hinting is used or not, but Freetype/Xft does not currently +support GASP tables (which are present in Vera). + +To mitigate this problem, both for Vera and other fonts, there will be +(very shortly) a new fontconfig 2.2 release that will, by default not +apply hints if the size is below 8 pixels. if you should have a font +that in fact has been hinted more agressively, you can use fontconfig +to note this exception. We believe this should improve many hinted +fonts in addition to Vera, though implemeting GASP support is likely +the right long term solution. + +Font rendering in Gnome or KDE is the combination of algorithms in +Xft2 and Freetype, along with hinting in the fonts themselves. It is +vital to have sufficient information to disentangle problems that you +may observe. + +Note that having your font rendering system set up correctly is vital +to proper judgement of problems of the fonts: + + # Freetype may or may not be configured to in ways that may + implement execution of possibly patented (in some parts of the world) + TrueType hinting algorithms, particularly at small sizes. Best + results are obtained while using these algorithms. + + # The freetype autohinter (used when the possibly patented + algorithms are not used) continues to improve with each release. If + you are using the autohinter, please ensure you are using an up to + date version of freetype before reporting problems. + + # Please identify what version of freetype you are using in any + bug reports, and how your freetype is configured. + + # Make sure you are not using the freetype version included in + XFree86 4.3, as it has bugs that significantly degrade most fonts, + including Vera. if you build XFree86 4.3 from source yourself, you may + have installed this broken version without intending it (as I + did). Vera was verified with the recently released Freetype 2.1.4. On + many systems, 'ldd" can be used to see which freetype shared library + is actually being used. + + # Xft/X Render does not (yet) implement gamma correction. This + causes significant problems rendering white text on a black background + (causing partial pixels to be insufficiently shaded) if the gamma of + your monitor has not been compensated for, and minor problems with + black text on a while background. The program "xgamma" can be used to + set a gamma correction value in the X server's color pallette. Most + monitors have a gamma near 2. + + # Note that the Vera family uses minimal delta hinting. Your + results on other systems when not used anti-aliased may not be + entirely satisfying. We are primarily interested in reports of + problems on open source systems implementing Xft2/fontconfig/freetype + (which implements antialiasing and hinting adjustements, and + sophisticated subpixel decimation on flatpanels). Also, the + algorithms used by Xft2 adjust the hints to integer widths and the + results are crisper on open source systems than on Windows or + MacIntosh. + + # Your fontconfig may (probably does) predate the release of + fontconfig 2.2, and you may see artifacts not present when the font is + used at very small sizes with hinting enabled. "vc-list -V" can be + used to see what version you have installed. + +We believe and hope that these fonts will resolve the problems +reported during beta test. The largest change is the reduction of +leading (interline spacing), which had annoyed a number of people, and +reduced Vera's utility for some applcations. The Vera monospace font +should also now make '0' and 'O' and '1' and 'l' more clearly +distinguishable. + +The version of these fonts is version 1.10. Fontconfig should be +choosing the new version of the fonts if both the released fonts and +beta test fonts are installed (though please discard them: they have +names of form tt20[1-12]gn.ttf). Note that older versions of +fontconfig sometimes did not rebuild their cache correctly when new +fonts are installed: please upgrade to fontconfig 2.2. "fc-cache -f" +can be used to force rebuilding fontconfig's cache files. + +If you note problems, please send them to fonts at gnome dot org, with +exactly which face and size and unicode point you observe the problem +at. The xfd utility from XFree86 CVS may be useful for this (e.g. "xfd +-fa sans"). A possibly more useful program to examine fonts at a +variety of sizes is the "waterfall" program found in Keith Packard's +CVS. + + $ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS login + Logging in to :pserver:anoncvs@keithp.com:2401/local/src/CVS + CVS password: + $ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS co waterfall + $ cd waterfall + $ xmkmf -a + $ make + # make install + # make install.man + +Again, please make sure you are running an up-to-date freetype, and +that you are only examining integer sizes. + +Reporting Problems +================== + +Please send problem reports to fonts at gnome org, with the following +information: + + 1. Version of Freetype, Xft2 and fontconfig + 2. Whether TT hinting is being used, or the autohinter + 3. Application being used + 4. Character/Unicode code point that has problems (if applicable) + 5. Version of which operating system + 6. Please include a screenshot, when possible. + +Please check the fonts list archives before reporting problems to cut +down on duplication. diff --git a/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/local.conf b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/local.conf new file mode 100644 index 000000000..a69f57515 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf-bitstream-vera-1.10/local.conf @@ -0,0 +1,32 @@ + + + + + + + serif + + Bitstream Vera Serif + + + + sans-serif + + Bitstream Vera Sans + + + + monospace + + Bitstream Vera Sans Mono + + + diff --git a/lib/plugins/rfpdf/lib/fonts/ttf2ufm/README.TXT b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/README.TXT new file mode 100644 index 000000000..7bb7e36cc --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/README.TXT @@ -0,0 +1,30 @@ +To embed TrueType fonts (.TTF) files, you need to extract the font metrics and +build the required tables using the provided utility (/fonts/ttf2ufm). + +TTF2UFM is a modified version of Mark Heath's TTF 2 PT1 converter +(http://ttf2pt1.sourceforge.net/) by Steven Wittens +(http://www.acko.net/blog/ufpdf). ttf2ufm, is included in /ttf2ufm-src. +The /fonts/ttf2ufm folder contains a compiled Windows binary. +TTF 2 UFM is identical to TTF 2 PT1 except that it also generates a .ufm file +for usage with makefontuni.php or makefontuni.rb. + + +Setting up a Truetype font for usage with UFPDF: + 1) Generate the font's .ufm metrics file by processing it with the provided + ttf2ufm program (modified ttf2pt1). For example: + $ ttf2ufm -a -F myfont.ttf + + 2) Run makefontuni_ruby.php with the .ttf and .ufm filenames as argument: + $ php -q makefontuni_ruby.php myfont.ttf myfont.ufm + + 3) Copy the resulting .rb, .z and .ctg.z file to the TCPDF font directory. + + 4) Rename php font files variations for bold and italic using the following schema: + [basic-font-name]b.rb for bold variation + [basic-font-name]i.rb for oblique variation + [basic-font-name]bi.rb for bold oblique variation + + 5) Rename the name of the font in the first line of each .rb file: + TCPDFFontDescriptor.define('dtlargotitalic') do |font| + becomes: + TCPDFFontDescriptor.define('dtlargoti') do |font| diff --git a/lib/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php new file mode 100644 index 000000000..017c8a09e --- /dev/null +++ b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php @@ -0,0 +1,313 @@ += 0 && $cc < 0xFFFF && $glyph) { + $cidtogidmap{$cc*2} = chr($glyph >> 8); + $cidtogidmap{$cc*2 + 1} = chr($glyph & 0xFF); + } + } + if($gn=='.notdef' && !isset($fm['MissingWidth'])) + $fm['MissingWidth']=$w; + } + elseif($code=='FontName') + $fm['FontName']=$param; + elseif($code=='Weight') + $fm['Weight']=$param; + elseif($code=='ItalicAngle') + $fm['ItalicAngle']=(double)$param; + elseif($code=='Ascender') + $fm['Ascender']=(int)$param; + elseif($code=='Descender') + $fm['Descender']=(int)$param; + elseif($code=='UnderlineThickness') + $fm['UnderlineThickness']=(int)$param; + elseif($code=='UnderlinePosition') + $fm['UnderlinePosition']=(int)$param; + elseif($code=='IsFixedPitch') + $fm['IsFixedPitch']=($param=='true'); + elseif($code=='FontBBox') + $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]); + elseif($code=='CapHeight') + $fm['CapHeight']=(int)$param; + elseif($code=='StdVW') + $fm['StdVW']=(int)$param; + } + if(!isset($fm['MissingWidth'])) + $fm['MissingWidth']=600; + + if(!isset($fm['FontName'])) + die('FontName not found'); + + $fm['Widths']=$widths; + + return $fm; +} + +function MakeFontDescriptor($fm) +{ + //Ascent + $asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000); + $fd="{'Ascent'=>".$asc; + //Descent + $desc=(isset($fm['Descender']) ? $fm['Descender'] : -200); + $fd.=",'Descent'=>".$desc; + //CapHeight + if(isset($fm['CapHeight'])) + $ch=$fm['CapHeight']; + elseif(isset($fm['CapXHeight'])) + $ch=$fm['CapXHeight']; + else + $ch=$asc; + $fd.=",'CapHeight'=>".$ch; + //Flags + $flags=0; + if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch']) + $flags+=1<<0; + $flags+=1<<5; + if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0) + $flags+=1<<6; + $fd.=",'Flags'=>".$flags; + //FontBBox + if(isset($fm['FontBBox'])) + $fbb=$fm['FontBBox']; + else + $fbb=array(0,$des-100,1000,$asc+100); + $fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'"; + //ItalicAngle + $ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0); + $fd.=",'ItalicAngle'=>".$ia; + //StemV + if(isset($fm['StdVW'])) + $stemv=$fm['StdVW']; + elseif(isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight'])) + $stemv=120; + else + $stemv=70; + $fd.=",'StemV'=>".$stemv; + //MissingWidth + if(isset($fm['MissingWidth'])) + $fd.=",'MissingWidth'=>".$fm['MissingWidth']; + $fd.='}'; + return $fd; +} + +function MakeWidthArray($fm) +{ + //Make character width array + $s="{"; + $cw=$fm['Widths']; + $els=array(); + $c=0; + foreach ($cw as $i => $w) + { + $els[] = ((($c++)%16==0)?"\n\t":'').$i.'=>'.$w; + } + $s .= implode(', ', $els); + $s.='}'; + return $s; +} + +function SaveToFile($file,$s,$mode='t') +{ + $f=fopen($file,'w'.$mode); + if(!$f) + die('Can\'t write to file '.$file); + fwrite($f,$s,strlen($s)); + fclose($f); +} + +function ReadShort($f) +{ + $a=unpack('n1n',fread($f,2)); + return $a['n']; +} + +function ReadLong($f) +{ + $a=unpack('N1N',fread($f,4)); + return $a['N']; +} + +function CheckTTF($file) +{ + //Check if font license allows embedding + $f=fopen($file,'rb'); + if(!$f) + die('Error: Can\'t open '.$file); + //Extract number of tables + fseek($f,4,SEEK_CUR); + $nb=ReadShort($f); + fseek($f,6,SEEK_CUR); + //Seek OS/2 table + $found=false; + for($i=0;$i<$nb;$i++) + { + if(fread($f,4)=='OS/2') + { + $found=true; + break; + } + fseek($f,12,SEEK_CUR); + } + if(!$found) + { + fclose($f); + return; + } + fseek($f,4,SEEK_CUR); + $offset=ReadLong($f); + fseek($f,$offset,SEEK_SET); + //Extract fsType flags + fseek($f,8,SEEK_CUR); + $fsType=ReadShort($f); + $rl=($fsType & 0x02)!=0; + $pp=($fsType & 0x04)!=0; + $e=($fsType & 0x08)!=0; + fclose($f); + if($rl and !$pp and !$e) + echo 'Warning: font license does not allow embedding'; +} + +/******************************************************************************* +* $fontfile: path to TTF file (or empty string if not to be embedded) * +* $ufmfile: path to UFM file * +*******************************************************************************/ +function MakeFont($fontfile,$ufmfile) +{ + //Generate a font definition file + set_magic_quotes_runtime(0); + if(!file_exists($ufmfile)) + die('Error: UFM file not found: '.$ufmfile); + $cidtogidmap = ''; + $fm=ReadUFM($ufmfile, $cidtogidmap); + $fd=MakeFontDescriptor($fm); + //Find font type + if($fontfile) + { + $ext=strtolower(substr($fontfile,-3)); + if($ext=='ttf') + $type='TrueTypeUnicode'; + else + die('Error: not a truetype font: '.$ext); + } + else + { + if($type!='TrueTypeUnicode') + die('Error: incorrect font type: '.$type); + } + //Start generation + $basename=strtolower(substr(basename($ufmfile),0,-4)); + $s='TCPDFFontDescriptor.define(\''.$basename."') do |font|\n"; + $s.=" font[:type]='".$type."'\n"; + $s.=" font[:name]='".$fm['FontName']."'\n"; + $s.=" font[:desc]=".$fd."\n"; + if(!isset($fm['UnderlinePosition'])) + $fm['UnderlinePosition']=-100; + if(!isset($fm['UnderlineThickness'])) + $fm['UnderlineThickness']=50; + $s.=" font[:up]=".$fm['UnderlinePosition']."\n"; + $s.=" font[:ut]=".$fm['UnderlineThickness']."\n"; + $s.=" font[:cw]=".MakeWidthArray($fm)."\n"; + $s.=" font[:enc]=''\n"; + $s.=" font[:diff]=''\n"; + if($fontfile) + { + //Embedded font + if(!file_exists($fontfile)) + die('Error: font file not found: '.$fontfile); + CheckTTF($fontfile); + $f=fopen($fontfile,'rb'); + if(!$f) + die('Error: Can\'t open '.$fontfile); + $file=fread($f,filesize($fontfile)); + fclose($f); + if(function_exists('gzcompress')) + { + $cmp=$basename.'.z'; + SaveToFile($cmp,gzcompress($file),'b'); + $s.=' font[:file]=\''.$cmp."'\n"; + echo 'Font file compressed ('.$cmp.')
    '; + + $cmp=$basename.'.ctg.z'; + SaveToFile($cmp,gzcompress($cidtogidmap),'b'); + echo 'CIDToGIDMap created and compressed ('.$cmp.')
    '; + $s.=' font[:ctg]=\''.$cmp."'\n"; + } + else + { + $s.='$file=\''.basename($fontfile)."'\n"; + echo 'Notice: font file could not be compressed (gzcompress not available)
    '; + + $cmp=$basename.'.ctg'; + $f = fopen($cmp, 'wb'); + fwrite($f, $cidtogidmap); + fclose($f); + echo 'CIDToGIDMap created ('.$cmp.')
    '; + $s.=' font[:ctg]=\''.$cmp."'\n"; + } + if($type=='Type1') + { + $s.=' font[:size1]='.$size1."\n"; + $s.=' font[:size2]='.$size2."\n"; + } + else + $s.=' font[:originalsize]='.filesize($fontfile)."\n"; + } + else + { + //Not embedded font + $s.=' font[:file]='."''\n"; + } + $s.="end\n"; + SaveToFile($basename.'.rb',$s); + echo 'Font definition file generated ('.$basename.'.rb'.')
    '; +} + +$arg = $GLOBALS['argv']; +if (count($arg) >= 3) { + ob_start(); + array_shift($arg); + MakeFont($arg[0], $arg[1]); + $t = ob_get_clean(); + print preg_replace('!!i', "\n", $t); +} +else { + print "Usage: makefontuni_ruby.php \n"; +} +?> \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm new file mode 100644 index 0000000000000000000000000000000000000000..26ecadef2138dac85ba7042a171d303f2b90669c GIT binary patch literal 173188 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm.exe b/lib/plugins/rfpdf/lib/fonts/ttf2ufm/ttf2ufm.exe new file mode 100644 index 0000000000000000000000000000000000000000..9109d5b2181cdd5e597863843309563dc473aba6 GIT binary patch literal 257984 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�A;O`VRLxg_~X=JCUP(4=Z{TZtWu~Bk{1T_#!ht!i=mH!Q^vwB_!zF zA%&|6dYQPpeFVLDVu7F)zb_)_PsH8lBk12XE_O+{_k6R6h5$xiYs5#x=QS>Ac>lRY zG?Wu}%tyoR3RgEY)hOJ#thtDoC^Jp^hFXV4*p1Qr2^-VSVtu#uWUsNO~kc3p6ZulIN{H_$P36xt%!AJGfG>MMAH@ z&qo(-ycN1Q6dOb7Ji662CdWa>oYbAhkild#dU%k6O2m_kSLRZh&s2CZ*lJLS{MoywNe>_;QatM_!2 z^_=U^im51cu-~g^gTlookGF6GZ#{m}3)s!zp9TIEdOJQQ0yYLhm5UY4zF82)DGr5B zH@lOt@u(?27R|z$!QQNKly?%IrilWYJ>eIPr2DnwNIbT(L^E7e1OxtESb^@N5Gnt{ zZkq)u@`NhgQxW1ZsWvLl{cPJNuYrTdvpjuF>TM_r+(=rx$+$uRvU24v6x4{dR}!bu zb+Vx=wa^F#jt+SwND0#$gLj-yK|k&H$hk!7sKzNRFe8xr4>ElNr|{}(hvIW_vS7+% z&p3)df)N#y=|lPFy#DD!31%bKM>lZ$U3z6Ckh=9Keb#%;iogbL%!ABLlSW7OHXcew zAUb+yT+g{Y9}Dx?dm2ngTE!|3b%$wyabR49Me_HV9d>_~X|89R zv_qYIDusOCjFNJnFQU+hDkwZInog6#_yl(8rN6_?o&j9TGW<8uh`pqTKEWbL{+l>*6yabv=m8i$<|oAA7zbWaIX{&tv$ z&7znv4^&vcdGHk2n1|2PJXBl{ajD@C&lI>Dj`f*`%dtHf+(}yVk**3fn=V30w@y$a zxuw!cRJTA1+!ww3NU`1-27xbnCVtI|60CtjhG`JIR!D?WNp#`}dKZV@NoP^-cr<#9 z>)q(Q{C$TrjC~B9h-U91yFC6M>h4ker>?+T6cNGcHQtzm^S;;wdnk29p?i%sqApxl z)cYE=0`W~bFxxfNUCE*ZLMm`jSBQB6(DZzHKGb~zm^c(vA_hWo*MVaNVvQslfjnK& z#$x=kVF$zcAEp;@M@L{)Sas}BOQ;Q9qo5_LD%A9G=uV&n79*ihiC^l$k=_M9sZVLq zl-o@(2R)K#GMz(h{_Exds$99V0>jI1Av%>&8DU>F zNRIrjWx9ZIebpqYj)ibO5@-8T^8kJ9P9|f|?xeJPlIL~TD3CcRjI_sAE0A$ey^PRj zopGyFqYn9sT3XkEKzEV&CLsm6o{+hI$Ro=Ou?Xq&L$(ldn;#N-A0W&8ki~?&#Sd9e$b3I! zKOqeY{e*1xL-rE#X+NZL z1t4qvkaj{o!((m*mr)UPop$DRRyoN1S=iJ=&Lp-kaJZ=^hOJshgpl*gT)km7q|25s$Q| zR|W$;a|~X{DMd(U-QsWw&+_99XWZ62&-F9R8wCJ8Mgu_1nRvxWrN~94oh4|}o0Tl_ zHVf+rbzM5Gu1NUsswRr7lIzlZRgrlIRL{Yc$h`#T*yBvd+J_!Q-3iyl*>o-kRoqNd zhT-|g8jv7>mwY^?0DqC0srMM7H6t-|o9ss^oViV|XK{uR7_WKad=lQX>O-&w{px=W zh7;BUhNgu=LUq26E!d;~F@(b#CDgqYylWv8=#>jM&jLt#FQjfsCzMVIVVVk*qo2jO7l0H;{9|y;G^S`qtUUsP}OmV(Xq9VIQAzt zrkIWfq2o2U?I+NUwpFuju}E30vMg4U!1<#q>9y?&<<#~s#RKF4)yPvRd1{ac@hx7F zfx8*8&9+MCc>pS68g_}~K~B_wo2_af4wdNt3dOA51tQ-pL{`Il)||pEbm*GKbT8^T z&q4W4S0!>+Aa^8bjgUz?h9A*cakXL%Qj0OAQzi@b{B(-Us8v?3`WCMzhXigeF{zQt z%X1rX%m(^{TWs3X&*R1#(fd{eEyk(%h%21{x6$TRl@ku%C6dzje&%A-rnNmiQhI4@ z5}Vw5op>dhP=O{u*6L8PvaDB2y_NJa83P$xf)r}f*fKmAsB3Acdn+Dr2OCZ|T!oTQ zMf+7KRn40j2C`NHL6!XbKeDAY?mjr;K;dngt-(}V5gm_s*h7L{3BS)t23a&XiQ9n2 zJ%leQ1ef>2p}2LeSFMeWuI?ROm|BA0#iX* zSH|n%uJfR60*$!mqJ|t6nZWr8r=5o+nz|-Ziwcqx!JaQK*9p2TgG<_xOSocf^3ZT0UgHa#- zlV|ZMsoUGJWLcVdy!#vsUdW6w4iV?gUf!R+B*wsf6nUW=>5nu9QkM!^BN)=2K3Ixt zfzF|jLc%4GyvNJCQRlrAc}0Qz6{d+$zIgPZr+KCChP=n=R&HTM8ohrfp*F*hH9yT zj>0Z%zQ)L>eTd|W1lGUK5*6cZ!#n`mU1RlojlBCsayg`~Rl490ynkrwvF1g%jA&|I zS7>droeWe{71MWTEAw9v&MjVPtx{U0wTFF1r{rD;H~WlY+$d9V9zY#npBdiAF~ugk zz)aP76?S`L{&p{&{S-$(QQ6r~S|f(NN}mMP9P67g>>VdVnDi4SY^~rddjR54i~e9& zwQ?EaNPW|W5{5*|P{Q=SsilE|ObP4LgXpRW9K)kDqGMRB>X>?uTcM*%dgwNzB@t;r zja3VXNcwO7C|rZ2%rn&RDn+zsvB>ig#oO>%!hq2}Ic3>3c_0=UetSKSRy1?^kN3*q zCC%!cDqR-p z)-$+Vqaf+nbtwEkOgcNgA|I3@E3KQ!XG-VG>JAt5`cqTnIC`Beg?=xV78Hr3GzfM_ z^Y)WscW4BflC|A6!jFok_Qvj6Xl;l4H8CE++^31gnTc?eG6MdQOTt>kJ@A4YReVZD z45LK0T4xI)^GWB6#^<88IjBu}j?!`WOLtY~WP<@cFI8ak z@X|`Jz{=sJbzXsW!%OFQ1sVr)Hk#6i!XXJ)=>lDW;PDL z&C^tB?wsMbdzwmBc&pe7t*N+%@xvllG(wP~*-|zHOvw;*mvW_~MQbm_MOkBNwLC)- zskn9mnPjw5vIdn7GKE-0a%JqV*VFOeD7m88fBW}*4vHo!P32s5Hr51+G__dTF8NDR z6}a7)%IC3;l-^ZmH3A|X_l6h6REkv1VFTK0n{cPy1=P!~N?vkX*%Yh6KUJc`JZ%VA!e;4=?60Rnry;-kU^Bd zp#@i{K|ifAuZ&Mg85K~Ob?sNJjgPPH9bXvjyAuT9>8j{m%TNZM;;YJYT`W#m$(CX+ z{5nyWwhpJI8EQez!DBri$yD68;MH=8)KZhL7uBS(opf3`glNoA%4qhnf?1g>RkZ6F zI|lsQtQrsL;20Z@g#dL&KK5kjo5#86iv6*4+9sXO9T+a!cF?@TW1Do^o`Ci)exe#T z=XoXFDc?uF;(C_pNoK!C zL#v_zbB^b7{1%2czdBKD*xM>uJ!V5wYg@0(KX`;{qJ29UfZ>Nxu3FnQyt;Q7lKCT% z%wb68-ADwCl9|Dyuwyo`ourXSJQ|6Vi37ea;8FO%3*?em<95hn0*$`u6jFuh(Ku~% zdmEt59d4I_jue&(%|d6ocdV=zUci```Ek2#UA1``!Ao8KKgCzAWpXRMCs0(|VU2iH zoF-IMcxBEtaa|Cw>HM=I(Hyc*S4b? z#{#>JihWVaGn9H-;oc$D&ka!Va}M-mMP*E0m3n9OucE$-F2`Os$F+OZL7U{4&wVL2!-Z956-S@ZLj+i z+Pb!-9dDNou4}!LoW=%cv7#X%a=BIKW&WaMJ`$0zlG2^%J`|%L!N1vF{u^}VL)Lr` zmQ-b;-gU`#wXJMzqCIyJgF5k$x7RG>+iSLFY!n1S_6s%+-{(N+x!EiAkH3_jcb~za zioig6B${?{1=1c&W!F5<4M^#iW_P2*_FxAWLYT40YXs<4*s&4uQ@*XXTFJ;IZd|gq zAyM1m-s3f&A9m$*c0V?#@0!tF9i=zbUjnN+klHZ0<_eOfs-%q{~72=U^+=8B=% zE|7%P=-qPT!wJ6k6_d?QY?mE-#EI{=--y=_5|pAY}ECgc}yeA#`Br zUSGX+ht*pR`VXsji>i04sn>g#dbilI%}#u)9e=n`?`Eg#Vbr@h;SR_kj(SH~FAQQ! zV*^K1@rU_Z+t6AgyF2_XeNff7$<*k*v&Q&?cKm*)Ym?peK%vI_o!A2qsQa;j)6|Gh z8({v0UKHQ|kC?|&RF!fc2{gD5CpmQ&Bx_BPNv&^s)jSaBV=B2hF$%wp4sc%Sf z6jCoW4N1<>ygsgDANv?w-LQxb@d$AC;6oao%B|8eRie?#?pzewd1Sv5iRG7J_%(A7|m@0V}MYw8d_n+!SLOg$H7E^TB~uPKe%bPcnl|0seWAppZ06r zKtJ^zy`O3tbU)P?VMjkfV-__wFl3ERDkxDsK2sw~RBvz#`b?XxZI$LuEwoTpuwbq{ zUUY(J#fv5Kqk2 zQpH!ACu6fclG>10k<>0vilk{!=^n!D%zXShS>oE+X8aaNl9U0$&^>%fxP!{IKCpCu z?(^sf>7(pGQ6Is6`TK}gewr@T7+sp)NA(Tub<_K(;lJHSb3nOb$Xt0+44DR%J|fH> zXvD9RA+DX7jo$)8Bqd82`iL(b?nB~`|FwNohrEiUdU;YLO@m4w5oTv<@atrWYiDcm zTOdhN1_(nR@g?Eb7?Sqq{y2$zjH{@LZy|b6|JG}v6>6boAr>W1gFgdR&?~Z-f^xkk zX+7YLTaQ1dJf=->ti>P(5eX`IE?j(|F2PW84M&C@yUV5KwbwvvBngAR_yS2d8p=OH zt`V7uO+_<%5yZlN_$CPFckP!i%3RmfxRe4 zQHqxfn%6*=eVfc5f)1Pp5dV;Ri#~*2P%QeaP6sI<`r{^jvgyU%n+8K| z9UTZ3jUgBeUG55TVNdBYKN0$MQv`LH^6@|cfRjOJEMoJ@8o00qN|%{&rNN^vGvoUT zfPyZQ3pHhm3!uZN%bo2bS(~x^}^zaALc0x{lOQFxL`M5IkYj~%<`(MtfGJ0u08K}2p`NQv`m}mdmlxNO!Xb(M zb{t`!VY_RPb99_`Wz1+WAZ&QVj%{(`gLZstfel-nt}WuEZME?gXJm1k`@gvoF~&0< zs%k5sxr*`wE$F|wx_`Egcvom;)^kk7}Jb&m>N(VFs?m_Dhs%m{BS;akJve!@`xW&2|@pPGRuhK%4jiHMh?W>;T!gAf;RnB_%VD&y(g*I!M!hnpyIy#nM7T>pTV6H9cOW)WDCk{BCu|gd*xMEBJ_En6(V8O zWi61Q?A)rPw|KhUGNZsp@aBSL!%HV6_SKE0?fjKKRe?kpm28tT##x5m!|GmAT*i2z zjPk9Rlopx<+gPwynB34_)qThW?#G@|P5So(MNJ|tZ&S8`6iJ8|Yk;&^zR0eM5}5r{ z=fis_!v)(|fRpGE9Ez#3E^u^8h2-?+Yi!N-*j@M5YpqVuf^rk?wPJsj$*jjz9}7f? zm}2X!ED%Ne5?r}4%RUKw$Y}(Yn`^6TZ4#gPP-|Z4mloqhxLTjZ{<~DIv;eKPyjK5V zue2I#NuR)iCh}odsLinAxO^}q3a1b4)XTUifX&97aIIIsH@yOqEC6#lz4I4kOj2LX zrYOviFwSE~O7rmB)NYGt=1ztWrdPt(%fcqE8!RxlNV#SMYs}Q zQQiU}77@c(IW9)W$ndUbwT?Gy9dC*D(a4f>@o_fp-9}XJn*sG6pw76kTH1?UbU2Dw z4HjX+^`@t*o$m1iZ6)=?*Pjg6X5zqg-yi1k;)K)rB;v_!PYx&W!UY^qjOp!Xa5@i{ zw*hwGx+jP84<3jO7q)dhSd?kRitf{VvJX=3e?K>arKHd1H|DV1Fp3<7Sm2}|p64T3PYu^~PR4zTTH2&U_Josx;K z3;AK|M(OIoAfunzomI+`utylD5v$VLI20QNDS_Nh{P2E+XdhOCK+;6QwG;`e8En_J z8c=9PKXB22t_d_mnsJNl{EDC%DGIS$S7^q2r5P6&H>0+J!6P&S_6N;CJOQt02JD<} zM)*k0sBPem0o9CJt$A|8!wtMYAoVUxeG~43`+Z%(`OPOaz_g+J4MNtZjw^6iv2$b^ zJMa9NuoM0Q+8oH=C~^GvGD4bK3RBYI&huBry6dM`b(vJvSX>pF3{zOtx3*}=pp zg_ym1g=M4wU>C0x|HKvc*4MhD|=gC(1=Ded1Kp6~ zQITSps@wfl#ZdQqrdI_iMpes;t3s2N9v7ONG*wN2xq;k;$bg)l6raX-Z)18i6XrW5 zs3}JhVUJL;B=wFrtyv{}7!%?H=IKzk&$x`82UDwDj{H85%oX+o<$3;!2o zq64EJUjolW7ZG1@dlVO=AwdJ>d!?haL!@5 z_{AS^!VH;>O^L={Y(ki#q9z)fl8rs|GQ|hw_}SFb7`;n|T|I<0VpC)EE*U{MA(~T-q?n-2EC^55tIE~rVxzl|>#cU3l!fb{#r)1Wlb(DioUIV5x z8#lvfW{=>^W>GGv`Zo{DHI3P|O^Mn9vum;UyolMgO)a&>%*GBr#1~_c70jbC_2GTU=dPAT94V6NQgWn!)CQF6PR7s&^02=#*+RBwZ~)jl*GD2 zxnZ&SbdSd2PV_%1Ljv8T5qwFv|53i;03Q6P4tImhei%=T0f7eb;|kI+Zg*p|3c~!W z49ZP^z^xHF-;EjwUDNrlRgf}7l%m_1uK$28SqLR zJj|*UV7E@e#itFck`TK=1OuwWO9|qGa%0e7x_9uHXg0%EQ*{r@EI`N~#EI#$E#=Fw z3?`$~kWT6v#3#AS`l_x+f<*KngkRNZ@ZAS-7P{<_u*Gat(Ytk$O6UvUEZHU-UVN+D z?UjhFT)T3Tg+BOF1;+$rC^pOvnVIZf9E2WpkQ1w1y%nh0>C7S$h3y%Gh(zIj3Yc{6 zdmHBI?Db(b!n>Z{XPt~$cMpKS}7j}N%Udxl{Vdn!RGle_$uS-gJ^~p z)UILqra6bMhW;wyFNb8F<0Km-JYt<~wGIUR+Yo^T)jjV{j)8PsIJ%lQPdg zd=_uEWvR7(OnubWBCN7L~!x zKCpC;6W=4_&0YkSWHuX=-~zV}6>l}*h94XiVfE1r4|B<;>^pp+h)_4IyS;Rq=o1Q!n9E4?mDqKf2?&C67Faz~YY?(TYqpY@EvhwJ zRcm~E(TWK>!4S6DVYm;IBZT`7k9HPk`pLg*7PySE-Y}xOa;F0OqkM?M4W}Q+O?kr% z^NkNL9Wi0PuHp0(rC8!Zm@hUA?Us0klNIQt8=K9z<=iN+5&57F2AZ9^6B`@c ztb&TL)!Ugd0I>x!%fHwHKfu4~ZT!VR`*Cbtbp%CCrZIV*&B?W3(SK3dl67!lq8Tjb z!2v)NDM9llILooPyWH*zlOTf}R3&1v*R-g%w@L^}z|1Tk>MNfBUO13HNupT^mcJt8pZc$rz+IP>Xt!L`!O zS?+Y8uJz&HGSvX1+t-H$y#VMFjHbP~Ifo%dX@b*NMXco)!76z`TLE()^UKYSG0`di!&*Oz@&T{8U)YV^p3{wp- zy1l<#&nhA2g`7jZ2KiI%d#)c8*{7Rq-wGscWG4B3C{g7sWTK#BSG$ zPu><(8v;d5R9bJajc7zrpD4Z}&R1VFYg5xqovIDXF>gYjih7zNYW{z#nc8rm<*Q~! z^D{G*qN9cxlsvHx1;F}pVtA5AE4&<%C$`5(jsPKfKEt9YSybE9UW2Zd;`GHnEs5NG zT!N=LA1l*Y8`@b6g4AD0-M$ec?uhG83aOhPrLb?To z9X5{ZUe?k;lMF5^o+oRY21ox1dXNjn}Y@|>XV+^&}gPA3~c-%HP zFj}JR^tVI@OoCs`CB>8M;+naNbtJoRhY=-_BV0HD!(?(B8zfvddIn$>4HLLr#0-vm z;If8M)=-!>pq<8mcIMvf`O7Nui6yf+1Zhr3@c9TTkmjf78A;SHv)iYQo~u<$SF7(| zm}KPAV>rZmeYuGB^a2^#>c#m(-P3M6!jpM;;#4iY}rwpD< z6$bUy7?i1vI9LiT&lmM5BfU-7rdA7;+Ypk7~%N(|p8ta=k%^ z{4grX=b80en5bl1_>7P{m}pu@vr6U&6AewqG=PbwsT`4oiTqTr0KH*UshN3Ar_!*+3hdBl|jr-?Wp8iR;C0npU&ZTCn6w#XUZX zMz>dMKH^(PO6TEbii#I0FC8VXMm=p*c2fLE$pH@tO!O$%{POIiOpA0@Fwuw!?W8c# z*vW($*b_?4%xkAn;fO8%alvQ)0@mb}fzs>saDoK|Q%_r*C(|~J0orF4d#2FoGi!7( zLtN~F`4jZ=+!a#Aw1A8l1LFi@5mCy%V|Kw5_>4w0``Vd2=hOaAd(MUEBiHocJgWu? zk8lADWWw|!Z8v+-bL;%thThhk@O&@2N*HFejEOUzr2i~3R?woEvK{V1&z`Y(&2ep) zwYwe73ddQE@?zMfMHZj(%W>Y*PFUXQGh>58?WAd?7xUK+(c0)zJ7)}{QMlkpD>RWT zEJ;Tg`+}*O( z2n(!aD4=u%JKS$5sN5RSpoX`OY=&vrZbBQ6H|AGwxZCPiSl7nQnX3D}!e5UKb6ECC zFPP06=c9d3A-ZI4qChFwi8&h)dwosrO<$HsJTCP&H8jIB^cu16VwP3mHI0d0MJLW< zqPq4GXCzeFOA2L2b=lf60rmI(Lds^7lI}`h*`277iG~+mlUSjz*-3Zz<*c+uu7L2a z3|!462z}@5eP1#y60Pv4eKac6f=;_7QJj5~FZ>^%;lnAW4Nnv3W#K|~ePteXxf*t8?{N)Xfdq9l3CiVwkl(isrgQN8z zH@b!#!M0o5RewR_Jnm#!0=B|^L)xFmayeFC+R^!JN_u4{Yd0#`;a)Lw?Gs+@Nq_Ax zY*g!(Qit7+O{+SJ1TAAs8rV4DaQ+O@)x~2lyQ-R z|AZ&?wwN3&_$U=DRSQ6R!6)@0W%MxgEW+v|*C%`4iG2u7Qb_6=SuZ_Rns;4vd#RIU z4fvp#{LMEAxz}+|&-Ti8sqQ*t#wQC~{@m~sP8bt;ry`51!C6w4yPc#BFs-So9Ul>i z_J14AQ9FlAd*-TaMi;G`m8RRO(NoZw4a}3U7JKl3z_CFace^bMta`r?b@X*EY?&2X z&U-ua2c&sRuup9hE8x_3sCkLuaPqnix6+qzolY2PStd_1h+9;tnO zUOVPO77Fd#?7?dVuG+UakUCe|w>aUhQj&(chgy_CP%za3AqBIYxD?Fx4!1+&vS~_m znM;-s^}=Hk&Bk|#P^-BSeA5?1{ps|e5SNgm3C@+=S7F*D^Y3HGo^)8 z+N|_WTyo?mCtUpMzs7z$?v@8GzN+Zs!vh=0hsNAVlv~{5Xw`n$V@98(`R?N{Vn%f| zD;J9D+AD<_xNmrd7MZk}T4d5@YLTQBS|qQ97U9*jXfB90J^LRIutjybx3ER(j7ajW zg$~8lRfD|13M#9O{y#BkR51xWI*dt!=&xw@ zq?sfM-zb<-lH|+RurOJ~DRDH!^b>mK@6n@1Bp`kesLFvpA)^xO-&zhKP$d+oDt>?) z9Lx4s{Dx#08UFjob?!gGGt^l)oQbWMV}^tJn_AeuhxM5mtXjCMLAq- z)ROd7DqSgRbUU@vH7}JFO;7Ze=Kmc#^OT;^PM`$y5-e%j8_f)%X4EFSifh)PQt1(B zh-(0g0eC*tv;!rr0VSsJ#T5kmYU>2xV5sSd?hpIw!>|A#VimZG-6KMP$EJS^RrhEC z<4ywSt8gVgp0NX0 zoq*9)l-WtdEoM=qN_>SY7TC{992qx1ET;MU8MDZQglEMH~ z_8D;+pbuF8!;Kvf1jxh-FjM%3$QXR9^I7mT4u`?^()^En;7Vk`5gwfFp905zCmoNk zGfqZ7eh|;%mY-dO-eL6=h*H#`u27SaGkhJu+vo^{lpi_C-H znw=O1Dk7^NZ!Q2}cVX?vW^7vzJWfw?DogOigl?Q4@*pBh5nSzGAbdGL&$9Z7W)F+Q zN+kc4e0lCM_SbvylU_g-FOBxUjf|_3-sqazARQ5#EU2R)AG9`gK^-rgiO=bmLtyj| zz51wThS8IdW_)KB8U{vBMf*pO#OU<}MpxbEF*@h*)W_%ou$a+GG+qg#>B(s!;#h}$ ztoX!Rq_^FtajL%8`yf(TBt02I=*rj&jH%&Bq`B}8LmkO~8LZv`F6$lTG+TaMPy>Ti z&;{7xf-dl-%hv_w#zfR17Oz3_72Bb3`X$u`M#g9f#!h>~{5+g}#NX=1Vp;!0as4}Lwe-UNnq{(UyBBZ2zIRZU4$UZ3~9|w`!Z+u zxJfSsYql@F6PqsgX+l(8ypc$1;mkuGK!wyp4^18vB4xJ;cGK7&_=tjT-Xme0F+6Q% zGN8F%RVmmq3&qFCL$8laI9i)yl)}T?%ywnec7?xoRd#c0z%IV-Pzo3inF?~ywWCROh zq!?!a7=4f5i<^kjFPB1$g?BU%?{$O_U$6S>#5|`Wa{LqN=S%QamTJx$ur*#}L$=c^ z$N6N5EmU}Ag0^c8YCaNB(( z|BzTTs4zzNh)j&(E=+oq#`k%ph3qhPUh+F^a6=Y_oMwE^1cRMM5c^s8?ZP|lC+-6f z^RN$|1II)q`fv2C75$OFT!B!v51Evvh;spRzRzoFbUQv$CV*0-DEw;KE?PnTxiIGw z;&k9tmVJL14m*LSc6D3Eu+{5k?SVhHk$n&ZG-3`lqlO@PR=L& znhay%I;Rw@!xq2kkQu;Xq#VC9JyM3tn_wM`hQm5Y%|>=8xW?+57BE{0+VfuIz7^iqqrA%Qc$QGrbBrj-0eg9a(N2G z;g(z)SE##S%u{V*EauHn_zdl8^tJ09cZt2oeTP0r*B&vmLOUA zHr(7qO7m^vmtiB!G}_>u6*qwHS{p0Y?%Khus<@dI>zWYU(iU`Hd|%H8F^iwx!%$aN zq|EF*VKD{-Rk=^le7rAvYGxaj-^@bjR*!oDB-J*pfUkTU)TV?_S(_d;*?e)5WrpcSjsrN2C1* zaUk9^35aKN!145gCW3w5wDXSg+*V>rUw{xU&Qnd(&j;ZamF7P;!;l~@hbIyRLkeTV zuMLWik#8=pT(kzCY3QylB0{R-*Wn~1208gmp?EI{0X4<;@XOcxinO~ZziLEpqi1rt zOt8BkuUTy+-0BmJ$t};x*R*=~l&reqm6VMSBETb{JRjz$AC}#C1~4Y!h8;YOU*x4C zKx8a|F)|Iiadt^=SI(Ty;mL@*8MI^jlyn@)87gkLxbg)feFUFv3a9Si8J2WMhGfn` zpD@pLC>dcWSh#aE->PU4y&8pw*wnSR7Z>)8Y9S%#4{J@+?mG~57*%=lPl(jFVzmjl zaCWB9FMh||Z&(aJ@WoW0Nn2}E1*&ruT#yFE(abkx3@42~OI_R#oNz?%+D*G_W;Tih z@#RU&{{WZ&rlzm=H9fmlHGR9ZW4Niyjb{Iq&qh;Uv2FA5T%1==n~r2pWgJ+<8%Gf% z#Gpf#NmR@)Y|4HaVrVuf5lQP|-@x$r$JmD2TvFUeENx`IhwvPSq-f^*YzuF$9gg0` zQ;GireWJt_=SXFQg?#^24cq5y*!VxH&iOT^aXJtDN(e3?4jjFU8yO0A#GC2=Pc|C% z6d!AlzHPzUDLPBm;fl?)-+3~FM29twrt3lJ4~U{tBN?wbQ0>m zi=MHvH+c9T>28FHalBZ%2L|nLYI)?NUdyNYRLlF62$w}Oe_}hh6aW$C5`t$A^{4~0 zq&&kTDVm@6z>%5fUo!VJeKJ8Eg`sVV(dUxbDkz)yh0aLVCxjN()a?2 z^b|StGSDXv%9J<7_C-0+KpkaZ=901Y6a~95tKy&vcknyKBRH21bh+L%3R9U&5tl;T z0I@H-c*u|tYBRqo!o%z;4ZhX9*uGU=iUdeeVK!AvRV19=aWa;h8cda?YBov%gCH5G zCWK3z_|BjT1(UHrZ zenlS}&GC~hMc4VWWAU>DXI3kVV0L9m?(H(=X5W1uCZ-SsK3d;>hM2KQZU8{MpUbvG zV($QE1XXMSy)k)E_Nhr0SaE%xAUctZtiRxXKcAmKmd=Zh^_(}2sTzIng6FXy~4(5Un^=} z(<{u3_FYEhpk`?v&M@T?VHqr$C;VLH#Wb}X!>&uh(d{~;OL~^!mmVchCpX0=d$=@t z1Svo7@GO;DGCjeEgln-LEGt;m^b02=YIO%TBXWtzSsIsE$35t@Y)~gK-EFvga(tz4s!!xfcv;5&R zWNI!rd{|YS4vO&X^a!e~Xh7}zaVJVc%#|w~#~K*b7;nJk??~YSa>A{XX%TPl;U!Qf ztG9;nx4Orx$D0Pr=~rhfF`?!ya_;YBG7-FKuoC`CS$sbxNZA*~kDB*9>o%2yv{yexmf!Y|uM&8|yIZ9-ml<5mI~jsN`*biB z6jza>QCOM0)T9Pgqa+hA=F`KO0jo?%U?$a9UVSzGRq#xeX_!Kn znsE8kG@+D+&Ud~k!u(k2j$dHo8pO0$W=TQwT@DOLCa=Wt1)#HV~j@8SU;%>*dr9|UmA}v)Q9)iEK z0A|HufTaw8@po2-l`1%Vcdn$vSBD9lx6@@V27Qc=vh8b9oKf`3WK+DN_jQL~mn&=U z6}|Yd+2oCn??osD9Db~C*1dIYDBvggZAU6An!R2ugI-$G3qmR`h_$U^F#Np~_KHv5 z__Wjzn|!RVlr1B&+D z4s&hYU+DLBA7Z~_X>USzb$miKAC$;8;3oi=c{vt25foPOc&v5`jGqkdc^CTrzV9Gx z9Ka2^Pve^dg;xVk|3B{D2Rg2+y7wQ+QkV#>j1pu}zzHI8z+m$*iJ>;KiR5UCV>D$X ztPrRThC1%x1PCC}1gyknBgqad`$1hC*5(_@ei}5E1Pvdr zY50ytA|&XkixBi>mX_Yq;C~=&1b0F>)dTj|MYJ~l(o|Wm)0sn6lv~#)?1+~Rx#oPz z{qe7+T)LWfZ+L8{W9Vmp@T$kM&%7Z!`kz8-?T80MaCze4+Utyzya(z=g{bggP@2lu zyEG&+JZ?= z5z7{eHN+`P@k_@n2t*E)DG5n7y>kQ=n%zsEBqHAVSf-FM=3}uyNxPz!sHds6Mq9uD%Nl+j=MO!P!AqJE|H$z2{Y>qv|Yg?pAdcg?aJVlh0Jqw7JQOV#0#_Q+8GE zG#X^-)pQv3@cI7N!zE##W~%z62iRDq8#glzP+dCoNN(_ZR=-Q1L3K3S^zXh9PwLit zRly|I5s>ko<#YqJL4m8$(k0hQWr3E%c32`JaM-^2PR+8G@>e5$qA6UK^diN-!bbbF zO0nHfYE@p5ir-6<^Xu|HuF-I3qc$ zfV){U`RO1FYjm%bBYuo>ni8d&6{%T+{!!r40p$7$N)CP17=^X3liVPD{Y0!d4~ZXvNP8Q0rO7u1c&q~lyxoyb;RgbIMd26aX}=%b(ryL1^; zRuD5BJc98aM<|Q0oVB>UDa~Kgk?w_cr(tn)e(O*Kt)e(gnbtI=xb$fN?-!Y@2N5f* zwA(rn63!Yk&J#K4m5KZ%CJb#+flwB&=R%H>r|>HvA7OvI`IB~A=Xj`TDH0SpIF4vk zBx-elJupo?RL6lT9(w5SY-FS8P*c|8T6~`U0WT6E&rFqWOq=Jl5Zj8@j(_YNBI7IJ z-Kyx&%{7a4rS{C-;`KUwvDpD%_bvS%Xa-Jd@R=iE+`X*S4MOs2keQ((&s)*it@(-P zc`T%NOulJeCBGK|06u=(y8KCQsZA1jTF7+`O}G;FZn@>>$S*yweX{O4EodGTOp_}( z%oF(o#^6!=w&At2NYDNQ_mBcPyLD(Hw$(ka&Ng|BxJ~XRJ;kJ!YIW?iW;X>p_e_L6 zvQtT89_Szn3IWOVSs5CB9Yeb*q%#HTyLhtscZgoCV94r4!zkxN6EM=+(mNnr$=8nB z#oG^ezMp{B-$7A3F?4F53th!LX5ZS9xQ~aFb^QSMvgm_Te*T3VU*W z<@Sv6_eA}nH*JR+T5CC@%Gt`(r0Q&?{v{%CNdIOZ(qC*BqY@NWB)AEn?{%J)2yTe! zYq@wc}sQs(vtJXWzdd0d0$=b|!6W@*aLe*@ye+Tv{&a1J^ zZwe0`zG@4v-gB~)6MnN1F~_!um`w-*?)uGH59o>EM<|N{3wpwFNy|RI+Kx-=5aC7< zq4fW-in(S33UoBK)g}gyk(Yf)sQos|Sg$Sx=95Sl4udawB-g zO4rbonU4~W7?wP~z0R?cM5@f!Vi`>o_YtrXVZ2HwVt_pfEMb{=yHfwauePIjDUOSE zEIGGkV{n?-n$+T&82o~G#*VUH&!$*|wh{kzQowTgWBe^QoEXx-`j7nVr#bWLo)D*? zYbUp7Bq*qVt)LEsZmbF352xT@uW|Lzk)WXdwSv|LG*?ZW4N7MeAn-L8G@P~KRcfvkS|Gz9dngMy0x&5h26t}V3rcB;a9wTLUgP5%+bGXu%M}Aj*X)b>* zgX1sS=hMmVf(B&PaSJ*>pji;8Og%{ zn1d77$T@N@0lU*Z{wG4vLdZ)U&cz8G6MdJoCCB>T;-!WuS0$;Gg&?*z05rzS2q6Ta zHqGFZ-pbHj*D$pT$0vRn5Yj-iY`Lu$>y zm8|k`|MAZHNsL%6yoJY-kn7!5=4GxhgU&WuMiUtxk0y2v9kz|qEOUcfvr#dLf9;x& zN^p$D`LLJTCDq-QV8QTG6luPkLsIo;9aOAr^^{h9^pN>y+s5u$iP{X45%S+K!8?Vn zoJ-s6QIXmW6E1Z#*W=S({n-=A`y^|m9NZ^qsvaeFHE1!Jg9$jVST}SyG1O^7@fdgO zA2#d`1?E1iT!}%Qu6H=04$MDmE>y#5Ga>V51BhmZ91(4UHwU=3zpb}<;C)=wZ%PRu zQEXgb_4Z#30<(W*rPF}Xivti13N@kqa_1`cs;DXr;D?K< zId5-7hzU^oqktGy9nSSWa3XmC=y2iv`o~M&&*O;!a(Z}Dn9WPxmrITWiCz*mX-uz3 zv08maH7cYDO_yl9kIhZ?dLOufjXnoH``_**57=-V$POH+>1X?1g>x>syXv>PzKtew z$-O6%4~kXFZ=h1F|0=N6&x@8lNLlh?rPVN5cHn+AvA^JFcHlw2%)pd7ctdJ$g?Ehm ztBB$brm_RqcpA^+++UH}&5%dDKarKcN~~{eCegF|JRTr|Gn^V{ab~XQ-OT_+FwbU7 zn4~q8Yz_h-xm$kD2^aKQ-Y6$kJujDY*` z&iOxzmCx>zUToL<^RfcU{|>9<%uI`5;kCcaC3kqK9lTxusNQ4N&@nR?kloy|qW4%L ze}+o*)+EnDBu~v|dx0TJ;0gdzPF0E|9$r^dN79iO#PTkOW#Zw^`ICu9Qb#!LwJ}IS zeoc^cs%`Y%R3+&wNhdKEy{(d@QY3M<(Ryrx&sFTNB0`N>k;Rj?iL*EDWkydJ501lm zIE|QOBSsmU?k`Nv=w*k{xSBj>Gv=6=f?VAnGIG5YcylP&-)XI`FoOp}#ZgJ!#ZlGh z9O0)iOpZWp77>jh$o>tzIpM`8C|mC)J12qaHcQXp&tBao~bf%DoxF;E)` zF>2zG-Xk0X-xwrmF(K(x+vALYD@76`(0j7&aYi6YQYn%cfhb9(sK^LdlDcrQ5op37 z;q^kZy0s=+Aa?f7?&vMN;P77IcxPv_@CGK#4z}6F#KWlqBIxrnS{RC}Kjctkf}jA%D0vLi zj+X>`N!w$x3>~wTd*QsJs?E=NPbwj`aNgryQ||K3UOR))QCEKWLS2HwZN0Mt_!2dr zG#o!72&&zI%rh54N;R%^!|&n(9Y}6oGdjW&Yu!TvqN+CDvT8UVpC)#d;&T1K)tm9q zu(ub}Qn6#R0(|L`tH+_}nf;O)XiGci>tjdv+Uhq{arsC|h+cs~L7Zme->>e?Z>EHeswm1yAzMg^YA1ih?@cQc|;mfl(v&Uk?rPtC^ zC&QvAFIx2KplI*8!d171Z&CO6Ur=w_npl5HtDdWA?_YO80pZY6SbxbPSKtPFhdp}v zw(nZ|9k$TX-=g3BG@1?{$HhKb$G}_Ez!G)V%zOvn8Z+}9l1hQiE^{Q}qfNJ}n^@|M z3Nrut_82axxW{md8`vybzm<7%Zf5XCPvd)$*m82S@=qUc=VjlNqb{<=QP*|7Lf!K3 zoKIbfI_gG6iyO{iJa*f>zjoydSFH)Vni%|TO)TP+?A2Rd!Fi`mG`$viF74latD&?a z$t@|@lQEZ+iNUMGv!-c+qFnbP9y-Z&u<1n1 zPkSBhxz+97&7HZmoo*V32UKf1+{KUL`VkJ}j|YyiZsd~ZII zP8XfI8&I$kPqS~u_#0C8LcY~N{VKBeedyOBdudP;RkvP@B?kXpz3v^0_ULvZF=&Wc zIL3_=Iip~>!Jk@p;5J={i>czQeh0G#25_?m-euOTe|bm) zbL#}NheB@l%q=7Wn3AFyI_wBA91!49Q~Tr91o)^q`0x!CVAW|Xsu2Ocw9XOW*I-br z_&xr6nnD&!`yb#I2(epLr=4)6jkeygzUzz0)74nCZlUkv>{m{Mh0jpPgUIuoS>P1M z&DOp>S#8BWQWkh1Kyw!<|unSgTmCI)(VtqgKOy+#G+pWHp+qA^JBF z)usJq>Hs%KrVe<$2ikf^SWK?dVuI1T@69(nM$cl2J)_ytyP(j4#l0hQNV7L0%@sW& zO$&lf_Chqy!=}9-_IeMu^&Uv%Upr3|=kU(d@Q$wf2TfL@I2`u69_8TWx<^@^4n?qz zcLzLuxY+sVvBFguI%IFXB?eh@q0_Lf%tsg`6GOvJys(A_VyJ(0Ft!27t$hCxZ!6=m z^|BTlkad?Wus&XqIUF^dvWDZOKajtw(u$2+{}CizE6a3?Ez|C`z>5}=KG7P?Wxv}N zBn90@NE^5T2X50#T7r@fyOM2FeV8ZamKEj=ExE0iw0d0)3vykTEHwIEkr|6H|AVwh z7BBsPxD$~zbr_UpX z@jDVj8M}73G^+ z9nUl^1o@C>;`fFt(3Ju5A5e5CWXDF{`NYXw=NZhpPn^nionaL}V8+A)421AZAFFl166&VwQPa8Q7IPp~_$(A707P-`w zd@gsN3;C2`9Z|Q8&!z4Y*WTI|_lW@PL;$vHmLsvN#47n1(Q#BRj}W`s5aT^iTfj8w zhi%di!vjqE0d9~R)`s>$=Z1GOWZ3IGGnV$c&K&E`Y>hzuZAt`aE+5GZMrn^&8j*}4 z_}*dD?S}!|mOL=!o5AZrfelu*(=8 zbLxH2a2J%_%hIx2^zO;*hi9`gE+d>h3i<_#SB+1Dy`n7is+ zH%BD0l~6>Dtw7-}n9?7V!@`M+6i zD9d^hE?~v=HSD1R(3(up&`D&Qs~@@lg5u}}uJ|E}FDl%2&KgJ2cl8bx*Eh6=;3-nm zTDVO>3d#E`71z&gXHNMFI)zP0Bf~brX???@(wOZ*4{6Qs_TOf{AJmOQm?$+VwVxlp zkbm*s4%-TJ+wMaDE|4v*f8tpA2c=)IJe1zW^H?9KXfp0r@VDViVqnollF~&M@_mtb z01OYAz0tsruhqcggEALa+COfa1Ju7Am1Qpn69loDVPt{-l?%%C$#M04*rAwg`N2e? zpUAP+Vv7lz1vv3hZ_-`^hpnTgH(1k6cmuo8MLDV5?)l_vT zjBRxd+%~5H*|J)T3r4Mx*Jvk(&1u~z7MZ%ybY>!I>6)M=Z9H0wb&p5n12F?pH+qp4 ziD0blf1^-0ls3kL#s4YO;;YA8HmhmKgJhYGEGNrvc~52v6wsN|{vUEnF!VAlb&=kz zjcb=058|5=gF14I%I|h?H<>L(`^`_1jC8TM(C=9g!lOGUScJA z#TIXFzV{SNU0`g1(Q~D8n$Zv!vb`Z4fo_|EQ$3mH2-frO5UiFm3tf~}wzN1>?)A3n zBIU-t{z4$-#((xTHW-)^IObb0-F%UR+1e#0%L<-eDxUJzBHExjKU-yFT)R+`O+P6- zVTC7&9h2dR%^;y=YnSLj;N(Q%EmEJ!D!#8ZlvamPHtv4&f z-cXp{P&n#MyY;5?g5E3-k-4xpOMk82w1)sL?9K8Edb8A-XV^>r6rCPsvE{8fOf}xT z)a)>gr7cLxDj~_zqBq0enSJgioBzjc{=;qY;_BsvjZ1^saLlRUW`sjZ$BP}Ug%5># z-5-aUEMpjImPP{Qb?R!>ZwW(f7jU+;+hf`VdrbRM73*i+gG1cpsVlZGEqtgwX#5=^ z{F$o!mcoZZ3*qa+{9mX2ADP_tUHj+ew(mRm#rF2X2bTwpKkhVe^&D+WWLZ?$80x8i z9%i23^1}0aUU$Pt`JB;bWwq)1oaG2`h?lms@9lQK&0G_bIwPyWW&6b(&7KQ2I2Q!rlNCWG1tYC0u!UXvmj^qOnXlKQQN)9tzL zcCWoN*P$lWby#H<#Xh&D)i7|SmgKrYUUXKXE=8m$&TOUVazo+oCO~5@jVYLP7o%jC zCaSC{$k6BDZ%UA3mJE-QQP@r6RR1jo-2F;xFoDELF^Fk zP1I&-T$7#PeyP6e9l97>#cp%Vh}Hm<;dD-wF|oW*t&yw;*7#`6t%de9z&E7jLnFT7 zyS?5yn-f;j=s6o=&;{ix7_dFK*obRfD<(|*WyUKZdpXWrl1nd%RD?U7a|Illv`rxbp@?b1> zO?$bqm^={HIiT-~Ga@ncZkB~&a=4HjsWKjN3b&1Pq!J=gj+)ej?Gu@{@_duS+*dHkmz6g30T_n%!h(B>6wCUsT+1h>ZbS&7p4pEw0VN zZR5q>vC0b5fl9U4+B|ba``O`c|D{364P#DsewoW2&S8n}I&&nKI?3@cVHwpJyU~=m zT=KpjChsex#)=!pC}3o`ZH%rL*FVZ=OnB>_IMRb%VL0vovFYsRQ-F)A%|wkuL_tHv z|)+`~0r;KG8nFT9bwwW#2$jWRPOy{uV+}5e7)=$%l*VNYC z$W2E42tvZWRjIA2z&PUJVd`^05pZT|#gi3j{ zjJZY5HF2)6sTM9h7t(|oIbGP)KoZBK7R36vbj^u=bwV5dP1@KmC^A&8&tU~6-WqrF zwX&VPbYKmD|>>QQuRorm$yi{py$g5)V zWFd93h^R@8JUv?6;7du_;4~Hje#7e!P@>CUw5(~HnV8VtEV}FH*=cn`K4l#>LKMj1 zhG50tJ(U>z7L)0`E^xF+fvf&a&yK%pgym!I*^HnIimwn5?`FDis-^Hj>%!dBrG*dv z8eLFe#Dr(=^toNAEfZBZ%S2&N6gL}}ze|HrdTZDR~#(YIVVmk)kDcOqpa0K!s201tE z4lT)S>aL$Uf==KTW!-5sGzdlHIKU_*6`<9VCvl;EVhojf)#CLm%%$1kGx?9;CaUrV zyIOdImzy_uWms!@Zp~7!XJszEEUZ=0-T-pEgT1aInje`qqhIMCgoEJEwyi-~b}_Ud zFk56R(7q_xRi=&<-;03yH4&RFcC;5(w}(5@BgI>nhuvJBTfNk~d1Y?xGO)02RZok!`$Nb>cE%#kUu{)CXF9~vNyaa?xx5Z>sD*w#-L?sD2yVX8r3TwdavQ$s)JZlVfmODkK{rl`JUi@+ZWx3ANj z&__qH`iZ=@M?!#d-Rv|YX%?ltkR)@Jij4UOTO|JiM4`{piwHj3)oG_)N@p^4g_dhxcWUZ`y{np(^El^UOuQ-_gjm5|)=sg_bXc#Pen8fBNqX+N~ zCm&3EDLHxyh`1@fY2i|vd@WTfb7H7f;3|VQ#S#>P!}PxC&CIt0CQ@G)g1q4=h8r*M z(d^N?dNQ+7U*5jV^(9yzS!f(9oOb&MG(_zm_C~l{7=%0?FsrPEC)56OHwpxX&5E6- zzBG$5UJLha2MYZs<$$Q@Yd44INKrS(P2C(PqO*2@mxTgua_Z)Iv2H9-F9}Q!@yd7M zBf!45;7Q`_LW(-94upj?w2Ml2Tc`^Ze8>N?F)CeCZO+&F!o~M{>$qElyUOR^uMb;u zat#kyVq;&4TmgoL2mwGOKjYKO8;uV-kO^~uJ4Y8`wL;( zqTKumOIxykGE7^Vo9|oNvi;}6wB@<^Q6F)M`|zGepG$IT>eTaO6`5T=ge`}OHOPXCK=9( zmGV)&6Wf)j|A?Qmy4Gc@P%k>+RcH;HFcJmD)ErG*gF)XF9#I0SDQ{YVjX?>DDkmsp zh}9P2h1Z7#$5ib~yEGuX%5dphlwCDLDq)Gn<5y%BZ4YhRAA7U$B4)u|wt~2FH+-9j znApQY>5&%b__MFMgmEP(HB3y#>5aGXTZS>LPLdiuHI zhN)t`AQe(m1uIqDFj*P>@YxzS`Zt-B(5Pj`jT|=0 z@|%N^5fx;E{1t;u6|>n!P9RQILVM@PwzVc;0JXwu+2hq9<{VF`iSv>Sueqg+$-*Qb zSviRqQk0VP##z2+(lQ3{{+2>oZtc$85mCAOO`>uq7R`@4Zq9z^6m7=(IJl)5;O)>) z`Gv8e%@WLA`cq^`b|4mYpx&(3EXiILs^}cg-!G4oM zW>V}D#I93I18KDG)Ur?S!p@# zH{o?O6Bn%!>qb=?_d3v&3gr#z3FY7G!1uqJ<}51OTU%%TADL?9DO;=1XTS&81lVzj z0PPcDPj{NFJN)G6A?R@QuuyuFS-Xxg4Mw{C-(7ybFiH&mi;3{Y7j9Dc(4|=6eNB!4 z?>CGm3Ri~o_%#ro2x~)+7e%akT9IYhmQ!g~YU zoEg5!+-J=p`S2V+wu9 z1bx3^2$&I!_HE8G*I4X`%lavE%b1Lm5Krco!05dFoUV1b<;2ht1R|Wok@Jz@E4%9O zo3_Vdi6MFV_vss*ZomFLF|;fyz1+SI-FRZCD@sd8UwwR0+m80@TV~_DeLSSUTnKWU z+@jSj7}VmI1t+i(f6czXyiO^uOx~q*T8h#OdCT3iGWz!R2=wUL`t3*ezHxi3_{t!v zGVh8AfH!1CChF@SPzkm$7HVmr3V8wd49n4H>bH+Rs3KPuhm>5f_N!VrWG$4g)=tNO ziiSFFuLh(8yASJa-M}&j_C)6s6Dr5Qlls@eJ27}>HEg>T=7sg`5 z)s@@mfbOOx6nm!kX>Zx%xxSGn@Bc4#wdEFCZ4%J{_ zE`}-tvqOl*d+u+QHn=R-;k_ua(KHaboB${)+0wAyq4UO^p}7yh(qpY~gDsEoHr>D7}z(xk@SI z^;h=G@i}BQE|h81eFXgepA`)h60|O8@j!j0$&m5L6P|?w4Zl|7dv>XC;1urTK1}_V zm>s%L9|V^eb#r-jmLppArQe36*@yHqL4+^7aAN3Aen_DX(7Nr|94g#)viRj+L4q$I z27;pkVdRV#;~hcL``1rQ+CcFZzPNLuZoyT?_#%9F(9weh+WJHj{N;?RS8^+;^J?%k5mjB~8Yn}T_qSpMH|=et0J>9``A zN=HSukm2q18;v8U*m#FPEvNn6u9{Z1uqF@#`rAF{ye6We+`tzU-7}}tZ}s*FCc&>! zLma}F4<I3^1Tc6pQI2MZa<4qL& z@})mC{wxfPhn}GA=f>faTQ=`|fQ=I8iDz~;e3h>qsb6gN<{z-M-q{DfuB7BIPb3E^ zY-YqkbM6ji2L@{ge$VS2l){%9yj=<^6bIps9fbprsySi1ErzwS~b)*`E`zsP(29dyu>gB-`qchwJ5OXjM-Ed8$F4r!%o zSG3a5M!poe6TYM;4-jtn^C=7++IlAvdG3s&gBPN;tt~Z~$P?g#Y`z1KhBq=*-?p;Y z$3yyCJFvmCG8zvn;Pnp{2W^xJUH>**s2h#)i|a?3L#m~b&D%%+w&LIuT_jN$f9|qW8)n5=pZ1Ubo1{`x@yp8uB{j$?-u$`-tclyaypnQ_N4-2|cI3lRWVezE zUlx6wIPUcJ=!dOOqLtRCly6ZE=XAQpD&&ly0hqjsK`*<3bDJ)|{!aneaLv0qXqlbU z9&1^9!9nv_Y{R%yI-rTYoj*l`Te#{$W{si4Edo&Xe~ZNae}u&6UYx|GFTwpMhL+M% z4KxI4OP%ZE;GDl$7vN1V=F-1Y{ajR~67a+e&WZ1l38}c-hB>6WZ5}e1iNS*cD+XtJ z4CxNLse#|(cf`$uTv+2%(_1#0JAB4wQs-!0Zt#pIZZyin0?{>uXNH20=lUMqVJc_W zqr1voRMslgIUg&&=HQh6S#~OS*u((pXI*Z$iGdetw(raiPi-O=%G}q&#AISW!Nhjx zBnSVYZ)n0zWS9FxP!6Z3YsBP_A)gv74!Mcza)7lS_}1efXIH)CSYYdmzdqPrEAGN^ zDo29F++pd4&PwTjSad<@cZhhjKWNw%Iv?E;`uu45i5)JNXp$W$=!W6CGrMxTA2sqi z0jO~;<3L3k=AATrwfOcYoEiBw81%QJIqs%!aY(Hcb~!Qd;v%3pbeENNQs4p!kPlat z>^Y2KK?qq_KT$IAaq)>Zbp1Fu{d|9N43&atQ&D_IpOdewy`Y3W?plJ-_i z6~y*T*qcR_-b|n_pXV5fdQ%k;`t1vg(S{$k;k(`tB0$u~Y^-kqcW15E_dB9*x1tEkjQ>X|3(zoEuvMpQ)vTh!zK##JWfEl9Y@9do3XzqnFs5eNLs z5O`WP9=qgML7vktPVOe6IC}Xe;$o(&p8!A3n|_D57%YM4L2C3O)vten>UbEa{(Xq1 za7G`XA{|c&m zaqN=u9{;^BRmHfjE53NU_&6@wZbI0tZc6*FxJnFE$9+!js<$n-ZmIEO3yiCveXgU4 zhO(b-iuJ!XGsd~{%ou}`Ii)}8!#BnJ54Naile=2(7cZ}g1s= zZ^vq!i6MT$jUx`f-!_nS7~sus?R$N-i!g0)4vdI5BJIKqIDtF@<@z|pr%1WZGbb~# z*aYWw!QBny3B!oF<`b$nUjD;8cNgS)iB!C$Bt+sxT@NuFtOXr?#sh28+aHU?+C|&k z+H{$yJSOVR+_A^u^YnK7a%AB;NMo?Il(S0FUH|_JqKk>#xflQbYizVD&ee|o_gZ!% zNBCf}tzrI}Xe}a)W*Vr)_ITmVfxx>ZEOjU* zhE+mQ+|mCY%eMnYeqESdX?MA@8PHha6XBVcr;VvF%~#sx`HYYRP1PhYPmq8A%Z;Lx z+0n5McntnJ3pJq*{Lz7ky1S}KuPf4v{FQ9H_h!kzdlRmS?BndHMPemxjS|_Y&ZT=R zbni=uXlv5j9=i{ajF`Y}T@!$_tn6bFCzfU4g2Y;v=&EmjM&#s{ao)iabsIN2(z;*Q z#bQk{B9VD31}pBa4a~ z3RNkrDg@R{n)e{6!#^syX^a39v}Y~35S8i6%G+Mpbd*4oN$d)M?~>&UFG+h{vGZ}9 zEWjr8P(Gn9C1WzPKsOiC#vCpbI3c9xHS`N*89)k?8a+JGp`m(ewM! zlS)n=DRez?PC4t(oGU++=eCeMP9p!CKXObJ-j_+Nq@8ZV)*qbUY$_6bl=5*6INCx9 z3#ptcbX~rP4Ek?k1XDjrH7%Ttb45g5JOv!RETm>QKolG#f>;(fOJ-A{i_jQlMyB+= z^f0&-0bkEvjo)fq83#SSyYV1B=<$sJftipAkM*-2JP0$vKKvZvp6S%VVnPA`G=IxMdA@){0k2Xuq#W%k8`D|>>y=k+RHl-Yi{2DjI_CIsVVWzC-F?ymR}!Sq|m#!2jZvw zKRv6#)j2ih&q0Liw(lXS51M4v&+UO^?c0Fy!NQ^PI%!Mji6XYKFr`p2P!(Y$UMHB$ zD;j*2ZCmRqE#;Gk(tdl?5;Dv{KOT$MLL}GNgVl}wj@Q4px-q8!obu8H)0{RQYtO+} z=}xXcH{g#?s~bU+LW05U@t=4m>>P`V@x)`Xc%3MV912oGk@M+`(fhU+=`>u&QE>3U zr3fCAhR5n^JQ!;hxLA9F$p|yF>+*Hd|37xIjV={ zhH50DVR>tWL}gg&xVYC*WQS2CM8+s`*TpDuK9A5k%IS;n$k%^*F&_Doe+(&d5o9VO zBT14Nd_=faOB1)-4~~9F$va?5o~{S29k|UzQyqyW%?@~d1mGP$lVJmBL3o2_%qSFO zW7eTW10^2S7LoJmOW40|)o1Ski!WpYKnc#J^s&jcnL9Yjru0x7ni;~*=7G&|53>tCDs$Csl3Pf7Qki4@?C4W)? z^RuC5{0_@#w7rTZ+R9gph>fMMa}?jLhIWAQa-=+RO8XKHx8%sQlh&AxnLKfHx5nXyISYrn4KbG*nGayH=Qzt{O2x$_R~t98^H=)%zX;u3s=GS^@D~n%)7RI&6pqrt zoZZ^d;&1sjy|qF707@G-o`#D?Amv^y%%}2QvFF>Kyr;urj}~*SDM(IXr_@!|!JB|BDlG*Y-|vYixaKv{BFl0Iw7pvN(Z4BS8snfUfOG zXD1RUYh@;WD0yq7TP*~pr^6FXTE!&KM`vIvmAUp5;+}mvXJ!KEmi-*6mH|&UU5hUE zOhRW1L2Sr;G0r1Hbd6R`mI;u#%G;wXI=MTY8ISt55gIZgwytySjq_3h5( z5p+Bzx{c^^IKc!P{eG&i)3aW+C3p9~!TNG#(3i|~1beSzS2s4LWo#@%$c;Jcco_p- z(5}?wkU}ogH9+)=X%~B~6IZ%2-I?ZWI45p!jg-De=N$QYsX^a)`zy`le(sW2iVY^$ z7aOQnSAeVEZ3r?8B8bnh^%nWL;=$Azksl$H6#0QAmF7!E6Ydp!z-VHl|BE_DZOET| zfSMYABe^m4Ra`$04)FDCcV=1CR)5e|@9ecURE+bGN#X!wb>3QZqwrBLb$|6Jyk9(O z9c^3F*zcy#TbWP1?4TYq*b+k5iGyf4sLBuS>55SJX~7Y-R$) zWR(i3=rXyV`2|SJC|T>7zNnGBHPTr6W1t#6u5{4SnXOTo54$pMh;#Xch*tSn^)E9v zH)J0M*(K_P(>pwutQeyQz{q+Vi`BrfZ`d-A@yU*ItBk?u@rUg8FLnzW9&L1a&5us7 z(fy(YyXpAF=i^WzU_@AFZ`f(ah4)uNNgR7RtU%MyWw)1e_&QQqA|sO+w3i3X$(21? zw}KmJ*c@@C_0k-RPwD_pQIM33?eTw`gTCy}&lkL(cm;xYP_)_=5p4NOj8UE7eG<=W zH8CnKm)>o1r|@@R+q{8~;rWB0^xXnE^lgD0_VJMZ)(&u2$TqvV^Z`PenI}qh9y)n* zza>29{S*(Xl2?x9R{ovWIfhaD@9N6m@XQ%${y%y2xSXcCIjds6o$BU(1II0(v{i9b zG&)__)K=^rYD?x0+WL$0+A2ARqng#FMh3+DmL|7TX&*Yxr&MT3&|KbD_&xfIOlzu_ zOsg-M$9_nO*TrB2JAa#>rCu(7j=$cX7+JYJQ~Dli*7r~yf4zK*zVmVZmKn(aDw`Xi zc6b56SgQcO(#scAojArlR=1-wH)Iv*zRTfh6>AL*bI6+dmZnqCi$%0SFKjZ~rt87$ zV$HRJjDG*1c3-wK1byj!klv{$PjQmid@J?_%^D$%R=-D1u`sw43#ztwLuusVE_L~#MI@&E z?ZHpt0HxjJ%{|$ZA5vjnRy?D^?3NOPZ`6)4qEqi7Pipw#Fr_`$JM2MFPDSOdeRT6Z z);OV*Lm6R_e_3_@HSLal!+CGp znCooA(wN5E*Iue6NYl(#c!;#?pQcYs$nKSGNBT~<_LB5Sk&s?TD97IQAwn5vE(-0{M%KpBh>Z7;2!)wtlx)vGKC1z zZyBVP@75u+C{PS+|9KrV6ScU~ZZhzNn*{t#q#NBc0k zEn>srT-T`uxW186c5m{wU@_>MKb-3uUFxlyeR;Av?Hd|c!FAdfn z%v-^-!|95BuBclA(*C6n+5B<^+HCIPEv+wo7z|L8di;c$m$)Z`$$e+0b1>AW{t5ZP z`comEQ7gw^Eg#DujdYH#Q_C2nQ%f~yTp33E^a4(SkG7;U=?Kyn4Uz_JeUvujpzD?~ z|8;K88#Z71i9=T^H)h<%C`%g_e`}CSL#(jq*rx55zQH!vYd8?Ht3JH>4_2|OzJn27 z(-;t8DO-kTpK`0fwU47ev;G?quE=bR(0rN&5+angMO@Ai@V4IFdW}m%irU-v#z-SZ zp{iCE+n&TqYIDL^LFL5?VpAO?-=mLjHz{Qo-fYy-QSZFaQR`W)ULQ-+;^F4)(gz}mJbO>UJUBNbAsrb4q!3Gwb+lv~!I z+l0BQU!xl>$R>@vkGJRgn&LW5%Ih62(-w6BF>HAY%oyKxLrxtJ_dDu5Ov8R>Th!Y- ze<^Ci^hR1E6uTV>`hbesFogt^K5x`RO9>QO`h}o$Vj$e5xHJJwXYP+$y2M(-6p8ur zey=0_QYptG%SiuX!;siQhoKE~I&(Ox`ZxcNAzAvIY=nW9Q@bK1O^#a>k1oyi9zdld zN)u7!Chr$6x0!UlCbv|6$T7h^6#@UK1MW1rmtaf|_H_=o#GvlIyy%Rq9q12zH7^c-m$^~xbAo9|gMG>9${KActn=rgkVIPic+a`a>6qXB* zU7qzyyF7hBcbP{pDcEGpv`6rg4qoXLF^rL952TF^a+_7b_LF5SZ1i9QK|!Mu6Cit> znzAN>`LE9jM`94IF$WdJie;$qQgt5@r<%uCzq6~t=gEpnQ9FQp!KR+;MRJ?AGT$$&)`!a@KYdiaX!W zP5qy`@T@JDxbY;#0M6WT+s%&skOLq6lXwR!&bQ>O!J9Sb+hQ)K!TzBm$-4KE(frFv zp^x3qz2@4e$3@zRV)4ZPD;FTk=xQaDW@x#1&EB}lW9vf4dA;Pm)4v* z_Cs8L=V3O-Er@3e7Q|M_OHRZR-~lY)B0N{n1*fTT(@Pt9N`(wAqd8Xo!zkjVH3$+4 zt}G#<2X=6(#2dW^>FJ!*l=j}UPnr*>H>DDFXO2XCaLKb`^%lBy`%_!@O?`AQHt%Tk zh(%9kl7hi&jfJ1PiJO|T_& z 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�YV6 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 literal 0 HcmV?d00001 diff --git a/lib/plugins/rfpdf/lib/fpdf/bookmark.rb b/lib/plugins/rfpdf/lib/fpdf/bookmark.rb new file mode 100644 index 000000000..a04ccd18d --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/bookmark.rb @@ -0,0 +1,99 @@ +# Translation of the bookmark class from the PHP FPDF script from Olivier Plathey +# Translated by Sylvain Lafleur and ?? with the help of Brian Ollenberger +# +# First added in 1.53b +# +# Usage is as follows: +# +# require 'fpdf' +# require 'bookmark' +# pdf = FPDF.new +# pdf.extend(PDF_Bookmark) +# +# This allows it to be combined with other extensions, such as the Chinese +# module. + +module PDF_Bookmark + def PDF_Bookmark.extend_object(o) + o.instance_eval('@outlines,@OutlineRoot=[],0') + super(o) + end + + def Bookmark(txt,level=0,y=0) + y=self.GetY() if y==-1 + @outlines.push({'t'=>txt,'l'=>level,'y'=>y,'p'=>self.PageNo()}) + end + + def putbookmarks + @nb=@outlines.size + return if @nb==0 + lru=[] + level=0 + @outlines.each_index do |i| + o=@outlines[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 and 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=@n+1 + @outlines.each_index do |i| + o=@outlines[i] + newobj + out('<>') + out('endobj') + end + # Outline root + newobj + @OutlineRoot=@n + out('<>') + out('endobj') + end + + def putresources + super + putbookmarks + end + + def putcatalog + super + if not @outlines.empty? + out('/Outlines '+@OutlineRoot.to_s+' 0 R') + out('/PageMode /UseOutlines') + end + end +end diff --git a/lib/plugins/rfpdf/lib/fpdf/chinese.rb b/lib/plugins/rfpdf/lib/fpdf/chinese.rb new file mode 100644 index 000000000..6218bb9a6 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/chinese.rb @@ -0,0 +1,486 @@ +# Copyright (c) 2006 4ssoM LLC +# 1.12 contributed by Ed Moss. +# +# 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 is direct port of chinese.php +# +# Chinese PDF support. +# +# Usage is as follows: +# +# require 'fpdf' +# require 'chinese' +# pdf = FPDF.new +# pdf.extend(PDF_Chinese) +# +# This allows it to be combined with other extensions, such as the bookmark +# module. + +module PDF_Chinese + + Big5_widths={' '=>250,'!'=>250,'"'=>408,'#'=>668,'$'=>490,'%'=>875,'&'=>698,'\''=>250, + '('=>240,')'=>240,'*'=>417,'+'=>667,','=>250,'-'=>313,'.'=>250,'/'=>520,'0'=>500,'1'=>500, + '2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>250,';'=>250, + '<'=>667,'='=>667,'>'=>667,'?'=>396,'@'=>921,'A'=>677,'B'=>615,'C'=>719,'D'=>760,'E'=>625, + 'F'=>552,'G'=>771,'H'=>802,'I'=>354,'J'=>354,'K'=>781,'L'=>604,'M'=>927,'N'=>750,'O'=>823, + 'P'=>563,'Q'=>823,'R'=>729,'S'=>542,'T'=>698,'U'=>771,'V'=>729,'W'=>948,'X'=>771,'Y'=>677, + 'Z'=>635,'['=>344,'\\'=>520,']'=>344,'^'=>469,'_'=>500,'`'=>250,'a'=>469,'b'=>521,'c'=>427, + 'd'=>521,'e'=>438,'f'=>271,'g'=>469,'h'=>531,'i'=>250,'j'=>250,'k'=>458,'l'=>240,'m'=>802, + 'n'=>531,'o'=>500,'p'=>521,'q'=>521,'r'=>365,'s'=>333,'t'=>292,'u'=>521,'v'=>458,'w'=>677, + 'x'=>479,'y'=>458,'z'=>427,'{'=>480,'|'=>496,'}'=>480,'~'=>667} + + GB_widths={' '=>207,'!'=>270,'"'=>342,'#'=>467,'$'=>462,'%'=>797,'&'=>710,'\''=>239, + '('=>374,')'=>374,'*'=>423,'+'=>605,','=>238,'-'=>375,'.'=>238,'/'=>334,'0'=>462,'1'=>462, + '2'=>462,'3'=>462,'4'=>462,'5'=>462,'6'=>462,'7'=>462,'8'=>462,'9'=>462,':'=>238,';'=>238, + '<'=>605,'='=>605,'>'=>605,'?'=>344,'@'=>748,'A'=>684,'B'=>560,'C'=>695,'D'=>739,'E'=>563, + 'F'=>511,'G'=>729,'H'=>793,'I'=>318,'J'=>312,'K'=>666,'L'=>526,'M'=>896,'N'=>758,'O'=>772, + 'P'=>544,'Q'=>772,'R'=>628,'S'=>465,'T'=>607,'U'=>753,'V'=>711,'W'=>972,'X'=>647,'Y'=>620, + 'Z'=>607,'['=>374,'\\'=>333,']'=>374,'^'=>606,'_'=>500,'`'=>239,'a'=>417,'b'=>503,'c'=>427, + 'd'=>529,'e'=>415,'f'=>264,'g'=>444,'h'=>518,'i'=>241,'j'=>230,'k'=>495,'l'=>228,'m'=>793, + 'n'=>527,'o'=>524,'p'=>524,'q'=>504,'r'=>338,'s'=>336,'t'=>277,'u'=>517,'v'=>450,'w'=>652, + 'x'=>466,'y'=>452,'z'=>407,'{'=>370,'|'=>258,'}'=>370,'~'=>605} + + def AddCIDFont(family,style,name,cw,cMap,registry) +#ActionController::Base::logger.debug registry.to_a.join(":").to_s + fontkey=family.downcase+style.upcase + unless @fonts[fontkey].nil? + Error("Font already added: family style") + end + i=@fonts.length+1 + name=name.gsub(' ','') + @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, 'CMap'=>cMap,'registry'=>registry} + end + + def AddCIDFonts(family,name,cw,cMap,registry) + AddCIDFont(family,'',name,cw,cMap,registry) + AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) + AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) + AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) + end + + def AddBig5Font(family='Big5',name='MSungStd-Light-Acro') + #Add Big5 font with proportional Latin + cw=Big5_widths + cMap='ETenms-B5-H' + registry={'ordering'=>'CNS1','supplement'=>0} +#ActionController::Base::logger.debug registry.to_a.join(":").to_s + AddCIDFonts(family,name,cw,cMap,registry) + end + + def AddBig5hwFont(family='Big5-hw',name='MSungStd-Light-Acro') + #Add Big5 font with half-witdh Latin + cw = {} + 32.upto(126) do |i| + cw[i.chr]=500 + end + cMap='ETen-B5-H' + registry={'ordering'=>'CNS1','supplement'=>0} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def AddGBFont(family='GB',name='STSongStd-Light-Acro') + #Add GB font with proportional Latin + cw=GB_widths + cMap='GBKp-EUC-H' + registry={'ordering'=>'GB1','supplement'=>2} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def AddGBhwFont(family='GB-hw',name='STSongStd-Light-Acro') + #Add GB font with half-width Latin + 32.upto(126) do |i| + cw[i.chr]=500 + end + cMap='GBK-EUC-H' + registry={'ordering'=>'GB1','supplement'=>2} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def GetStringWidth(s) + if(@current_font['type']=='Type0') + return GetMBStringWidth(s) + else + return super(s) + end + end + + def GetMBStringWidth(s) + #Multi-byte version of GetStringWidth() + l=0 + cw=@current_font['cw'] + nb=s.length + i=0 + while(i0 and s[nb-1]=="\n") + nb-=1 + end + b=0 + if(border) + if(border==1) + border='LTRB' + b='LRT' + b2='LR' + else + b2='' + b2='L' unless border.to_s.index('L').nil? + b2=b2+'R' unless border.to_s.index('R').nil? + b=(border.to_s.index('T')) ? (b2+'T') : b2 + end + end + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(iwmax) + #Automatic line break + if(sep==-1 or i==j) + if(i==j) + i+=ascii ? 1 : 2 + end + Cell(w,h,s[j,i-j],b,2,align,fill) + else + Cell(w,h,s[j,sep-j],b,2,align,fill) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + nl+=1 + if(border and nl==2) + b=b2 + end + else + i+=ascii ? 1 : 2 + end + end + #Last chunk + if(border and not border.to_s.index('B').nil?) + b+='B' + end + Cell(w,h,s[j,i-j],b,2,align,fill) + + # move cursor to specified position + 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 + @y = prevy; + @x = prevx + w; + elsif (ln == 2) + # go to the bottom-left of the cell + @x = prevx; + end + end + + def Write(h,txt,link='',fill=0) + if(@current_font['type']=='Type0') + MBWrite(h,txt,link,fill) + else + super(h,txt,link,fill) + end + end + + def MBWrite(h,txt,link,fill=0) + #Multi-byte version of Write() + cw=@current_font['cw'] + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + s=txt.gsub("\r",'') + nb=s.length + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(iwmax) + #Automatic line break + if(sep==-1 or i==j) + if(@x>@l_margin) + #Move to next line + @x=@l_margin + @y+=h + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + i+=1 + nl+=1 + next + end + if(i==j) + i+=ascii ? 1 : 2 + end + Cell(w,h,s[j,i-j],0,2,'',fill,link) + else + Cell(w,h,s[j,sep-j],0,2,'',fill,link) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + if(nl==1) + @x=@l_margin + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + end + nl+=1 + else + i+=ascii ? 1 : 2 + end + end + #Last chunk + if(i!=j) + Cell(l*@font_size/1000.0,h,s[j,i-j],0,0,'',fill,link) + end + end + +private + + def putfonts() + nf=@n + @diffs.each do |diff| + #Encodings + newobj() + out('<>') + out('endobj') + end + # mqr=get_magic_quotes_runtime() + # set_magic_quotes_runtime(0) + @font_files.each_pair do |file, info| + #Font file embedding + newobj() + @font_files[file]['n']=@n + if(defined('FPDF_FONTPATH')) + file=FPDF_FONTPATH+file + end + size=filesize(file) + if(!size) + Error('Font file not found') + end + out('<>') + f=fopen(file,'rb') + putstream(fread(f,size)) + fclose(f) + out('endobj') + end +# + # set_magic_quotes_runtime(mqr) +# + @fonts.each_pair do |k, font| + #Font objects + newobj() + @fonts[k]['n']=@n + out('<>') + out('endobj') + if(font['type']!='core') + #Widths + newobj() + cw=font['cw'] + s='[' + 32.upto(255) do |i| + s+=cw[i.chr]+' ' + end + out(s+']') + out('endobj') + #Descriptor + newobj() + s='<>') + out('endobj') + end + end + end + end + + def putType0(font) + #Type0 + 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('<>') + out('/FontDescriptor '+(@n+1).to_s+' 0 R') + if(font['CMap']=='ETen-B5-H') + w='13648 13742 500' + elsif(font['CMap']=='GBK-EUC-H') + w='814 907 500 7716 [500]' + else + # ActionController::Base::logger.debug font['cw'].keys.sort.join(' ').to_s + # ActionController::Base::logger.debug font['cw'].values.join(' ').to_s + 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 + } + w +=']' + end + out('/W ['+w+']>>') + out('endobj') + #Font descriptor + newobj() + out('<>') + out('endobj') + end +end diff --git a/lib/plugins/rfpdf/lib/fpdf/fpdf_eps.rb b/lib/plugins/rfpdf/lib/fpdf/fpdf_eps.rb new file mode 100644 index 000000000..98ca53e6f --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/fpdf_eps.rb @@ -0,0 +1,139 @@ +# Information +# +# PDF_EPS class from Valentin Schmidt ported to ruby by Thiago Jackiw (tjackiw@gmail.com) +# working for Mingle LLC (www.mingle.com) +# Release Date: July 13th, 2006 +# +# Description +# +# This script allows to embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files. +# Only vector drawing is supported, not text or bitmap. Although the script was successfully +# tested with various AI format versions, best results are probably achieved with files that +# were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2). +# +# ImageEps(string file, float x, float y [, float w [, float h [, string link [, boolean useBoundingBox]]]]) +# +# Same parameters as for regular FPDF::Image() method, with an additional one: +# +# useBoundingBox: specifies whether to position the bounding box (true) or the complete canvas (false) +# at location (x,y). Default value is true. +# +# First added to the Ruby FPDF distribution in 1.53c +# +# Usage is as follows: +# +# require 'fpdf' +# require 'fpdf_eps' +# pdf = FPDF.new +# pdf.extend(PDF_EPS) +# pdf.ImageEps(...) +# +# This allows it to be combined with other extensions, such as the bookmark +# module. + +module PDF_EPS + def ImageEps(file, x, y, w=0, h=0, link='', use_bounding_box=true) + data = nil + if File.exists?(file) + File.open(file, 'rb') do |f| + data = f.read() + end + else + Error('EPS file not found: '+file) + end + + # Find BoundingBox param + regs = data.scan(/%%BoundingBox: [^\r\n]*/m) + regs << regs[0].gsub(/%%BoundingBox: /, '') + if regs.size > 1 + tmp = regs[1].to_s.split(' ') + @x1 = tmp[0].to_i + @y1 = tmp[1].to_i + @x2 = tmp[2].to_i + @y2 = tmp[3].to_i + else + Error('No BoundingBox found in EPS file: '+file) + end + f_start = data.index('%%EndSetup') + f_start = data.index('%%EndProlog') if f_start === false + f_start = data.index('%%BoundingBox') if f_start === false + + data = data.slice(f_start, data.length) + + f_end = data.index('%%PageTrailer') + f_end = data.index('showpage') if f_end === false + data = data.slice(0, f_end) if f_end + + # save the current graphic state + out('q') + + k = @k + + # Translate + if use_bounding_box + dx = x*k-@x1 + dy = @hPt-@y2-y*k + else + dx = x*k + dy = -y*k + end + tm = [1,0,0,1,dx,dy] + out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', + tm[0], tm[1], tm[2], tm[3], tm[4], tm[5])) + + if w > 0 + scale_x = w/((@x2-@x1)/k) + if h > 0 + scale_y = h/((@y2-@y1)/k) + else + scale_y = scale_x + h = (@y2-@y1)/k * scale_y + end + else + if h > 0 + scale_y = $h/((@y2-@y1)/$k) + scale_x = scale_y + w = (@x2-@x1)/k * scale_x + else + w = (@x2-@x1)/k + h = (@y2-@y1)/k + end + end + + if !scale_x.nil? + # Scale + tm = [scale_x,0,0,scale_y,0,@hPt*(1-scale_y)] + out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', + tm[0], tm[1], tm[2], tm[3], tm[4], tm[5])) + end + + data.split(/\r\n|[\r\n]/).each do |line| + next if line == '' || line[0,1] == '%' + len = line.length + # next if (len > 2 && line[len-2,len] != ' ') + cmd = line[len-2,len].strip + case cmd + when 'm', 'l', 'v', 'y', 'c', 'k', 'K', 'g', 'G', 's', 'S', 'J', 'j', 'w', 'M', 'd' + out(line) + + when 'L' + line[len-1,len]='l' + out(line) + + when 'C' + line[len-1,len]='c' + out(line) + + when 'f', 'F' + out('f*') + + when 'b', 'B' + out(cmd + '*') + end + end + + # restore previous graphic state + out('Q') + Link(x,y,w,h,link) if link + end +end diff --git a/lib/plugins/rfpdf/lib/fpdf/japanese.rb b/lib/plugins/rfpdf/lib/fpdf/japanese.rb new file mode 100644 index 000000000..0aa55081b --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/japanese.rb @@ -0,0 +1,481 @@ +# Copyright (c) 2006 4ssoM LLC +# 1.12 contributed by Ed Moss. +# +# 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 is direct port of japanese.php +# +# Japanese PDF support. +# +# Usage is as follows: +# +# require 'fpdf' +# require 'chinese' +# pdf = FPDF.new +# pdf.extend(PDF_Japanese) +# +# This allows it to be combined with other extensions, such as the bookmark +# module. + +module PDF_Japanese + + SJIS_widths={' ' => 278, '!' => 299, '"' => 353, '#' => 614, '$' => 614, '%' => 721, '&' => 735, '\'' => 216, + '(' => 323, ')' => 323, '*' => 449, '+' => 529, ',' => 219, '-' => 306, '.' => 219, '/' => 453, '0' => 614, '1' => 614, + '2' => 614, '3' => 614, '4' => 614, '5' => 614, '6' => 614, '7' => 614, '8' => 614, '9' => 614, ':' => 219, ';' => 219, + '<' => 529, '=' => 529, '>' => 529, '?' => 486, '@' => 744, 'A' => 646, 'B' => 604, 'C' => 617, 'D' => 681, 'E' => 567, + 'F' => 537, 'G' => 647, 'H' => 738, 'I' => 320, 'J' => 433, 'K' => 637, 'L' => 566, 'M' => 904, 'N' => 710, 'O' => 716, + 'P' => 605, 'Q' => 716, 'R' => 623, 'S' => 517, 'T' => 601, 'U' => 690, 'V' => 668, 'W' => 990, 'X' => 681, 'Y' => 634, + 'Z' => 578, '[' => 316, '\\' => 614, ']' => 316, '^' => 529, '_' => 500, '`' => 387, 'a' => 509, 'b' => 566, 'c' => 478, + 'd' => 565, 'e' => 503, 'f' => 337, 'g' => 549, 'h' => 580, 'i' => 275, 'j' => 266, 'k' => 544, 'l' => 276, 'm' => 854, + 'n' => 579, 'o' => 550, 'p' => 578, 'q' => 566, 'r' => 410, 's' => 444, 't' => 340, 'u' => 575, 'v' => 512, 'w' => 760, + 'x' => 503, 'y' => 529, 'z' => 453, '{' => 326, '|' => 380, '}' => 326, '~' => 387} + + def AddCIDFont(family,style,name,cw,cMap,registry) + fontkey=family.downcase+style.upcase + unless @fonts[fontkey].nil? + Error("CID font already added: family style") + end + i=@fonts.length+1 + @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-120,'ut'=>40,'cw'=>cw, + 'CMap'=>cMap,'registry'=>registry} + end + + def AddCIDFonts(family,name,cw,cMap,registry) + AddCIDFont(family,'',name,cw,cMap,registry) + AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) + AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) + AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) + end + + def AddSJISFont(family='SJIS') + #Add SJIS font with proportional Latin + name='KozMinPro-Regular-Acro' + cw=SJIS_widths + cMap='90msp-RKSJ-H' + registry={'ordering'=>'Japan1','supplement'=>2} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def AddSJIShwFont(family='SJIS-hw') + #Add SJIS font with half-width Latin + name='KozMinPro-Regular-Acro' + 32.upto(126) do |i| + cw[i.chr]=500 + end + cMap='90ms-RKSJ-H' + registry={'ordering'=>'Japan1','supplement'=>2} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def GetStringWidth(s) + if(@current_font['type']=='Type0') + return GetSJISStringWidth(s) + else + return super(s) + end + end + + def GetSJISStringWidth(s) + #SJIS version of GetStringWidth() + l=0 + cw=@current_font['cw'] + nb=s.length + i=0 + while(i=161 and o<=223) + #Half-width katakana + l+=500 + i+=1 + else + #Full-width character + l+=1000 + i+=2 + end + end + return l*@font_size/1000 + end + + def MultiCell(w,h,txt,border=0,align='L',fill=0,ln=1) + if(@current_font['type']=='Type0') + SJISMultiCell(w,h,txt,border,align,fill,ln) + else + super(w,h,txt,border,align,fill,ln) + end + end + + def SJISMultiCell(w,h,txt,border=0,align='L',fill=0,ln=1) + + # save current position + prevx = @x; + prevy = @y; + + #Output text with automatic or explicit line breaks + cw=@current_font['cw'] + if(w==0) + w=@w-@r_margin-@x + end + wmax=(w-2*@c_margin)*1000/@font_size + s=txt.gsub("\r",'') + nb=s.length + if(nb>0 and s[nb-1]=="\n") + nb-=1 + end + b=0 + if(border) + if(border==1) + border='LTRB' + b='LRT' + b2='LR' + else + b2='' + b2='L' unless border.to_s.index('L').nil? + b2=b2+'R' unless border.to_s.index('R').nil? + b=(border.to_s.index('T')) ? (b2+'T') : b2 + end + end + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(i=161 and o<=223) + #Half-width katakana + l+=500 + n=1 + sep=i + else + #Full-width character + l+=1000 + n=2 + sep=i + end + if(l>wmax) + #Automatic line break + if(sep==-1 or i==j) + if(i==j) + i+=n + end + Cell(w,h,s[j,i-j],b,2,align,fill) + else + Cell(w,h,s[j,sep-j],b,2,align,fill) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + nl+=1 + if(border and nl==2) + b=b2 + end + else + i+=n + if(o>=128) + sep=i + end + end + end + #Last chunk + if(border and not border.to_s.index('B').nil?) + b+='B' + end + Cell(w,h,s[j,i-j],b,2,align,fill) + + # move cursor to specified position + 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 + @y = prevy; + @x = prevx + w; + elsif (ln == 2) + # go to the bottom-left of the cell + @x = prevx; + end + end + + def Write(h,txt,link='',fill=0) + if(@current_font['type']=='Type0') + SJISWrite(h,txt,link,fill) + else + super(h,txt,link,fill) + end + end + + def SJISWrite(h,txt,link,fill=0) + #SJIS version of Write() + cw=@current_font['cw'] + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + s=txt.gsub("\r",'') + nb=s.length + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(i=161 and o<=223) + #Half-width katakana + l+=500 + n=1 + sep=i + else + #Full-width character + l+=1000 + n=2 + sep=i + end + if(l>wmax) + #Automatic line break + if(sep==-1 or i==j) + if(@x>@l_margin) + #Move to next line + @x=@l_margin + @y+=h + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + i+=n + nl+=1 + next + end + if(i==j) + i+=n + end + Cell(w,h,s[j,i-j],0,2,'',fill,link) + else + Cell(w,h,s[j,sep-j],0,2,'',fill,link) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + if(nl==1) + @x=@l_margin + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + end + nl+=1 + else + i+=n + if(o>=128) + sep=i + end + end + end + #Last chunk + if(i!=j) + Cell(l*@font_size/1000.0,h,s[j,i-j],0,0,'',fill,link) + end + end + +private + + def putfonts() + nf=@n + @diffs.each do |diff| + #Encodings + newobj() + out('<>') + out('endobj') + end + # mqr=get_magic_quotes_runtime() + # set_magic_quotes_runtime(0) + @font_files.each_pair do |file, info| + #Font file embedding + newobj() + @font_files[file]['n']=@n + if(defined('FPDF_FONTPATH')) + file=FPDF_FONTPATH+file + end + size=filesize(file) + if(!size) + Error('Font file not found') + end + out('<>') + f=fopen(file,'rb') + putstream(fread(f,size)) + fclose(f) + out('endobj') + end + # set_magic_quotes_runtime(mqr) + @fonts.each_pair do |k, font| + #Font objects + newobj() + @fonts[k]['n']=@n + out('<>') + out('endobj') + if(font['type']!='core') + #Widths + newobj() + cw=font['cw'] + s='[' + 32.upto(255) do |i| + s+=cw[i.chr]+' ' + end + out(s+']') + out('endobj') + #Descriptor + newobj() + s='<>') + out('endobj') + end + end + end + end + + def putType0(font) + #Type0 + 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('<>') + 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('<>') + out('endobj') + end +end diff --git a/lib/plugins/rfpdf/lib/fpdf/korean.rb b/lib/plugins/rfpdf/lib/fpdf/korean.rb new file mode 100644 index 000000000..550ab6560 --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/korean.rb @@ -0,0 +1,449 @@ +# Copyright (c) 2006 4ssoM LLC +# 1.12 contributed by Ed Moss. +# +# 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 is direct port of korean.php +# +# Korean PDF support. +# +# Usage is as follows: +# +# require 'fpdf' +# require 'chinese' +# pdf = FPDF.new +# pdf.extend(PDF_Korean) +# +# This allows it to be combined with other extensions, such as the bookmark +# module. + +module PDF_Korean + +UHC_widths={' ' => 333, '!' => 416, '"' => 416, '#' => 833, '$' => 625, '%' => 916, '&' => 833, '\'' => 250, + '(' => 500, ')' => 500, '*' => 500, '+' => 833, ',' => 291, '-' => 833, '.' => 291, '/' => 375, '0' => 625, '1' => 625, + '2' => 625, '3' => 625, '4' => 625, '5' => 625, '6' => 625, '7' => 625, '8' => 625, '9' => 625, ':' => 333, ';' => 333, + '<' => 833, '=' => 833, '>' => 916, '?' => 500, '@' => 1000, 'A' => 791, 'B' => 708, 'C' => 708, 'D' => 750, 'E' => 708, + 'F' => 666, 'G' => 750, 'H' => 791, 'I' => 375, 'J' => 500, 'K' => 791, 'L' => 666, 'M' => 916, 'N' => 791, 'O' => 750, + 'P' => 666, 'Q' => 750, 'R' => 708, 'S' => 666, 'T' => 791, 'U' => 791, 'V' => 750, 'W' => 1000, 'X' => 708, 'Y' => 708, + 'Z' => 666, '[' => 500, '\\' => 375, ']' => 500, '^' => 500, '_' => 500, '`' => 333, 'a' => 541, 'b' => 583, 'c' => 541, + 'd' => 583, 'e' => 583, 'f' => 375, 'g' => 583, 'h' => 583, 'i' => 291, 'j' => 333, 'k' => 583, 'l' => 291, 'm' => 875, + 'n' => 583, 'o' => 583, 'p' => 583, 'q' => 583, 'r' => 458, 's' => 541, 't' => 375, 'u' => 583, 'v' => 583, 'w' => 833, + 'x' => 625, 'y' => 625, 'z' => 500, '{' => 583, '|' => 583, '}' => 583, '~' => 750} + + def AddCIDFont(family,style,name,cw,cMap,registry) + fontkey=family.downcase+style.upcase + unless @fonts[fontkey].nil? + Error("Font already added: family style") + end + i=@fonts.length+1 + name=name.gsub(' ','') + @fonts[fontkey]={'i'=>i,'type'=>'Type0','name'=>name,'up'=>-130,'ut'=>40,'cw'=>cw, + 'CMap'=>cMap,'registry'=>registry} + end + + def AddCIDFonts(family,name,cw,cMap,registry) + AddCIDFont(family,'',name,cw,cMap,registry) + AddCIDFont(family,'B',name+',Bold',cw,cMap,registry) + AddCIDFont(family,'I',name+',Italic',cw,cMap,registry) + AddCIDFont(family,'BI',name+',BoldItalic',cw,cMap,registry) + end + + def AddUHCFont(family='UHC',name='HYSMyeongJoStd-Medium-Acro') + #Add UHC font with proportional Latin + cw=UHC_widths + cMap='KSCms-UHC-H' + registry={'ordering'=>'Korea1','supplement'=>1} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def AddUHChwFont(family='UHC-hw',name='HYSMyeongJoStd-Medium-Acro') + #Add UHC font with half-witdh Latin + 32.upto(126) do |i| + cw[i.chr]=500 + end + cMap='KSCms-UHC-HW-H' + registry={'ordering'=>'Korea1','supplement'=>1} + AddCIDFonts(family,name,cw,cMap,registry) + end + + def GetStringWidth(s) + if(@current_font['type']=='Type0') + return GetMBStringWidth(s) + else + return super(s) + end + end + + def GetMBStringWidth(s) + #Multi-byte version of GetStringWidth() + l=0 + cw=@current_font['cw'] + nb=s.length + i=0 + while(i0 and s[nb-1]=="\n") + nb-=1 + end + b=0 + if(border) + if(border==1) + border='LTRB' + b='LRT' + b2='LR' + else + b2='' + b2='L' unless border.to_s.index('L').nil? + b2=b2+'R' unless border.to_s.index('R').nil? + b=(border.to_s.index('T')) ? (b2+'T') : b2 + end + end + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(iwmax) + #Automatic line break + if(sep==-1 or i==j) + if(i==j) + i+=ascii ? 1 : 2 + end + Cell(w,h,s[j,i-j],b,2,align,fill) + else + Cell(w,h,s[j,sep-j],b,2,align,fill) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + nl+=1 + if(border and nl==2) + b=b2 + end + else + i+=ascii ? 1 : 2 + end + end + #Last chunk + if(border and not border.to_s.index('B').nil?) + b+='B' + end + Cell(w,h,s[j,i-j],b,2,align,fill) + + # move cursor to specified position + 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 + @y = prevy; + @x = prevx + w; + elsif (ln == 2) + # go to the bottom-left of the cell + @x = prevx; + end + end + + def Write(h,txt,link='',fill=0) + if(@current_font['type']=='Type0') + MBWrite(h,txt,link,fill) + else + super(h,txt,link,fill) + end + end + + def MBWrite(h,txt,link,fill=0) + #Multi-byte version of Write() + cw=@current_font['cw'] + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + s=txt.gsub("\r",'') + nb=s.length + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(iwmax) + #Automatic line break + if(sep==-1 or i==j) + if(@x>@l_margin) + #Move to next line + @x=@l_margin + @y+=h + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + i+=1 + nl+=1 + next + end + if(i==j) + i+=ascii ? 1 : 2 + end + Cell(w,h,s[j,i-j],0,2,'',fill,link) + else + Cell(w,h,s[j,sep-j],0,2,'',fill,link) + i=(s[sep].chr==' ') ? sep+1 : sep + end + sep=-1 + j=i + l=0 + if(nl==1) + @x=@l_margin + w=@w-@r_margin-@x + wmax=(w-2*@c_margin)*1000/@font_size + end + nl+=1 + else + i+=ascii ? 1 : 2 + end + end + #Last chunk + if(i!=j) + Cell(l*@font_size/1000.0,h,s[j,i-j],0,0,'',fill,link) + end + end + +private + + def putfonts() + nf=@n + @diffs.each do |diff| + #Encodings + newobj() + out('<>') + out('endobj') + end + # mqr=get_magic_quotes_runtime() + # set_magic_quotes_runtime(0) + @font_files.each_pair do |file, info| + #Font file embedding + newobj() + @font_files[file]['n']=@n + if(defined('FPDF_FONTPATH')) + file=FPDF_FONTPATH+file + end + size=filesize(file) + if(!size) + Error('Font file not found') + end + out('<>') + f=fopen(file,'rb') + putstream(fread(f,size)) + fclose(f) + out('endobj') + end + # set_magic_quotes_runtime(mqr) + @fonts.each_pair do |k, font| + #Font objects + newobj() + @fonts[k]['n']=@n + out('<>') + out('endobj') + if(font['type']!='core') + #Widths + newobj() + cw=font['cw'] + s='[' + 32.upto(255) do |i| + s+=cw[i.chr]+' ' + end + out(s+']') + out('endobj') + #Descriptor + newobj() + s='<>') + out('endobj') + end + end + end + end + + def putType0(font) + #Type0 + 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('<>') + out('/FontDescriptor '+(@n+1).to_s+' 0 R') + if(font['CMap']=='KSCms-UHC-HW-H') + w='8094 8190 500' + else + 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 + } + w +=']' + end + out('/W ['+w+']>>') + out('endobj') + #Font descriptor + newobj() + out('<>') + out('endobj') + end +end diff --git a/lib/plugins/rfpdf/lib/fpdf/makefont.rb b/lib/plugins/rfpdf/lib/fpdf/makefont.rb new file mode 100644 index 000000000..ffc98b48f --- /dev/null +++ b/lib/plugins/rfpdf/lib/fpdf/makefont.rb @@ -0,0 +1,1787 @@ +#!/usr/bin/env ruby +# +# Utility to generate font definition files +# Version: 1.1 +# Date: 2006-07-19 +# +# Changelog: +# Version 1.1 - Brian Ollenberger +# - Fixed a very small bug in MakeFont for generating FontDef.diff. + +Charencodings = { +# Central Europe + 'cp1250' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', '.notdef', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + '.notdef', 'perthousand', 'Scaron', 'guilsinglleft', + 'Sacute', 'Tcaron', 'Zcaron', 'Zacute', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + '.notdef', 'trademark', 'scaron', 'guilsinglright', + 'sacute', 'tcaron', 'zcaron', 'zacute', + 'space', 'caron', 'breve', 'Lslash', + 'currency', 'Aogonek', 'brokenbar', 'section', + 'dieresis', 'copyright', 'Scedilla', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'Zdotaccent', + 'degree', 'plusminus', 'ogonek', 'lslash', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'aogonek', 'scedilla', 'guillemotright', + 'Lcaron', 'hungarumlaut', 'lcaron', 'zdotaccent', + 'Racute', 'Aacute', 'Acircumflex', 'Abreve', + 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla', + 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', + 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron', + 'Dcroat', 'Nacute', 'Ncaron', 'Oacute', + 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply', + 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut', + 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls', + 'racute', 'aacute', 'acircumflex', 'abreve', + 'adieresis', 'lacute', 'cacute', 'ccedilla', + 'ccaron', 'eacute', 'eogonek', 'edieresis', + 'ecaron', 'iacute', 'icircumflex', 'dcaron', + 'dcroat', 'nacute', 'ncaron', 'oacute', + 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide', + 'rcaron', 'uring', 'uacute', 'uhungarumlaut', + 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent' + ], +# Cyrillic + 'cp1251' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'afii10051', 'afii10052', 'quotesinglbase', 'afii10100', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + 'Euro', 'perthousand', 'afii10058', 'guilsinglleft', + 'afii10059', 'afii10061', 'afii10060', 'afii10145', + 'afii10099', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + '.notdef', 'trademark', 'afii10106', 'guilsinglright', + 'afii10107', 'afii10109', 'afii10108', 'afii10193', + 'space', 'afii10062', 'afii10110', 'afii10057', + 'currency', 'afii10050', 'brokenbar', 'section', + 'afii10023', 'copyright', 'afii10053', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'afii10056', + 'degree', 'plusminus', 'afii10055', 'afii10103', + 'afii10098', 'mu', 'paragraph', 'periodcentered', + 'afii10071', 'afii61352', 'afii10101', 'guillemotright', + 'afii10105', 'afii10054', 'afii10102', 'afii10104', + 'afii10017', 'afii10018', 'afii10019', 'afii10020', + 'afii10021', 'afii10022', 'afii10024', 'afii10025', + 'afii10026', 'afii10027', 'afii10028', 'afii10029', + 'afii10030', 'afii10031', 'afii10032', 'afii10033', + 'afii10034', 'afii10035', 'afii10036', 'afii10037', + 'afii10038', 'afii10039', 'afii10040', 'afii10041', + 'afii10042', 'afii10043', 'afii10044', 'afii10045', + 'afii10046', 'afii10047', 'afii10048', 'afii10049', + 'afii10065', 'afii10066', 'afii10067', 'afii10068', + 'afii10069', 'afii10070', 'afii10072', 'afii10073', + 'afii10074', 'afii10075', 'afii10076', 'afii10077', + 'afii10078', 'afii10079', 'afii10080', 'afii10081', + 'afii10082', 'afii10083', 'afii10084', 'afii10085', + 'afii10086', 'afii10087', 'afii10088', 'afii10089', + 'afii10090', 'afii10091', 'afii10092', 'afii10093', + 'afii10094', 'afii10095', 'afii10096', 'afii10097' + ], +# Western Europe + 'cp1252' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft', + 'OE', '.notdef', 'Zcaron', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + 'tilde', 'trademark', 'scaron', 'guilsinglright', + 'oe', '.notdef', 'zcaron', 'Ydieresis', + 'space', 'exclamdown', 'cent', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Eth', 'Ntilde', 'Ograve', 'Oacute', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Yacute', 'Thorn', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'eth', 'ntilde', 'ograve', 'oacute', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'yacute', 'thorn', 'ydieresis' + ], +# Greek + 'cp1253' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + '.notdef', 'perthousand', '.notdef', 'guilsinglleft', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + '.notdef', 'trademark', '.notdef', 'guilsinglright', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'dieresistonos', 'Alphatonos', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', '.notdef', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'afii00208', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'tonos', 'mu', 'paragraph', 'periodcentered', + 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright', + 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos', + 'iotadieresistonos','Alpha', 'Beta', 'Gamma', + 'Delta', 'Epsilon', 'Zeta', 'Eta', + 'Theta', 'Iota', 'Kappa', 'Lambda', + 'Mu', 'Nu', 'Xi', 'Omicron', + 'Pi', 'Rho', '.notdef', 'Sigma', + 'Tau', 'Upsilon', 'Phi', 'Chi', + 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis', + 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos', + 'upsilondieresistonos','alpha', 'beta', 'gamma', + 'delta', 'epsilon', 'zeta', 'eta', + 'theta', 'iota', 'kappa', 'lambda', + 'mu', 'nu', 'xi', 'omicron', + 'pi', 'rho', 'sigma1', 'sigma', + 'tau', 'upsilon', 'phi', 'chi', + 'psi', 'omega', 'iotadieresis', 'upsilondieresis', + 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef' + ], +# Turkish + 'cp1254' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + 'circumflex', 'perthousand', 'Scaron', 'guilsinglleft', + 'OE', '.notdef', '.notdef', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + 'tilde', 'trademark', 'scaron', 'guilsinglright', + 'oe', '.notdef', '.notdef', 'Ydieresis', + 'space', 'exclamdown', 'cent', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Gbreve', 'Ntilde', 'Ograve', 'Oacute', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'gbreve', 'ntilde', 'ograve', 'oacute', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'dotlessi', 'scedilla', 'ydieresis' + ], +# Hebrew + 'cp1255' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + 'circumflex', 'perthousand', '.notdef', 'guilsinglleft', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + 'tilde', 'trademark', '.notdef', 'guilsinglright', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclamdown', 'cent', 'sterling', + 'afii57636', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'multiply', 'guillemotleft', + 'logicalnot', 'sfthyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'middot', + 'cedilla', 'onesuperior', 'divide', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'afii57799', 'afii57801', 'afii57800', 'afii57802', + 'afii57793', 'afii57794', 'afii57795', 'afii57798', + 'afii57797', 'afii57806', '.notdef', 'afii57796', + 'afii57807', 'afii57839', 'afii57645', 'afii57841', + 'afii57842', 'afii57804', 'afii57803', 'afii57658', + 'afii57716', 'afii57717', 'afii57718', 'gereshhebrew', + 'gershayimhebrew','.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'afii57664', 'afii57665', 'afii57666', 'afii57667', + 'afii57668', 'afii57669', 'afii57670', 'afii57671', + 'afii57672', 'afii57673', 'afii57674', 'afii57675', + 'afii57676', 'afii57677', 'afii57678', 'afii57679', + 'afii57680', 'afii57681', 'afii57682', 'afii57683', + 'afii57684', 'afii57685', 'afii57686', 'afii57687', + 'afii57688', 'afii57689', 'afii57690', '.notdef', + '.notdef', 'afii299', 'afii300', '.notdef' + ], +# Baltic + 'cp1257' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', '.notdef', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + '.notdef', 'perthousand', '.notdef', 'guilsinglleft', + '.notdef', 'dieresis', 'caron', 'cedilla', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + '.notdef', 'trademark', '.notdef', 'guilsinglright', + '.notdef', 'macron', 'ogonek', '.notdef', + 'space', '.notdef', 'cent', 'sterling', + 'currency', '.notdef', 'brokenbar', 'section', + 'Oslash', 'copyright', 'Rcommaaccent', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'AE', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'oslash', 'onesuperior', 'rcommaaccent', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'ae', + 'Aogonek', 'Iogonek', 'Amacron', 'Cacute', + 'Adieresis', 'Aring', 'Eogonek', 'Emacron', + 'Ccaron', 'Eacute', 'Zacute', 'Edotaccent', + 'Gcommaaccent', 'Kcommaaccent', 'Imacron', 'Lcommaaccent', + 'Scaron', 'Nacute', 'Ncommaaccent', 'Oacute', + 'Omacron', 'Otilde', 'Odieresis', 'multiply', + 'Uogonek', 'Lslash', 'Sacute', 'Umacron', + 'Udieresis', 'Zdotaccent', 'Zcaron', 'germandbls', + 'aogonek', 'iogonek', 'amacron', 'cacute', + 'adieresis', 'aring', 'eogonek', 'emacron', + 'ccaron', 'eacute', 'zacute', 'edotaccent', + 'gcommaaccent', 'kcommaaccent', 'imacron', 'lcommaaccent', + 'scaron', 'nacute', 'ncommaaccent', 'oacute', + 'omacron', 'otilde', 'odieresis', 'divide', + 'uogonek', 'lslash', 'sacute', 'umacron', + 'udieresis', 'zdotaccent', 'zcaron', 'dotaccent' + ], +# Vietnamese + 'cp1258' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', + 'circumflex', 'perthousand', '.notdef', 'guilsinglleft', + 'OE', '.notdef', '.notdef', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + 'tilde', 'trademark', '.notdef', 'guilsinglright', + 'oe', '.notdef', '.notdef', 'Ydieresis', + 'space', 'exclamdown', 'cent', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Abreve', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'gravecomb', 'Iacute', 'Icircumflex', 'Idieresis', + 'Dcroat', 'Ntilde', 'hookabovecomb', 'Oacute', + 'Ocircumflex', 'Ohorn', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Uhorn', 'tildecomb', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'abreve', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'acutecomb', 'iacute', 'icircumflex', 'idieresis', + 'dcroat', 'ntilde', 'dotbelowcomb', 'oacute', + 'ocircumflex', 'ohorn', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'uhorn', 'dong', 'ydieresis' + ], +# Thai + 'cp874' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'Euro', '.notdef', '.notdef', '.notdef', + '.notdef', 'ellipsis', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', 'quoteleft', 'quoteright', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai', + 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai', + 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai', + 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai', + 'thothanthai', 'thonangmonthothai', 'thophuthaothai', 'nonenthai', + 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai', + 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai', + 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai', + 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai', + 'ruthai', 'lolingthai', 'luthai', 'wowaenthai', + 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai', + 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai', + 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai', + 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai', + 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef', + '.notdef', '.notdef', '.notdef', 'bahtthai', + 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai', + 'saraaimaimalaithai', 'lakkhangyaothai', 'maiyamokthai', 'maitaikhuthai', + 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai', + 'thanthakhatthai', 'nikhahitthai', 'yamakkanthai', 'fongmanthai', + 'zerothai', 'onethai', 'twothai', 'threethai', + 'fourthai', 'fivethai', 'sixthai', 'seventhai', + 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai', + '.notdef', '.notdef', '.notdef', '.notdef' + ], +# Western Europe + 'ISO-8859-1' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclamdown', 'cent', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Eth', 'Ntilde', 'Ograve', 'Oacute', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Yacute', 'Thorn', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'eth', 'ntilde', 'ograve', 'oacute', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'yacute', 'thorn', 'ydieresis' + ], +# Central Europe + 'ISO-8859-2' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'Aogonek', 'breve', 'Lslash', + 'currency', 'Lcaron', 'Sacute', 'section', + 'dieresis', 'Scaron', 'Scedilla', 'Tcaron', + 'Zacute', 'hyphen', 'Zcaron', 'Zdotaccent', + 'degree', 'aogonek', 'ogonek', 'lslash', + 'acute', 'lcaron', 'sacute', 'caron', + 'cedilla', 'scaron', 'scedilla', 'tcaron', + 'zacute', 'hungarumlaut', 'zcaron', 'zdotaccent', + 'Racute', 'Aacute', 'Acircumflex', 'Abreve', + 'Adieresis', 'Lacute', 'Cacute', 'Ccedilla', + 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', + 'Ecaron', 'Iacute', 'Icircumflex', 'Dcaron', + 'Dcroat', 'Nacute', 'Ncaron', 'Oacute', + 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'multiply', + 'Rcaron', 'Uring', 'Uacute', 'Uhungarumlaut', + 'Udieresis', 'Yacute', 'Tcommaaccent', 'germandbls', + 'racute', 'aacute', 'acircumflex', 'abreve', + 'adieresis', 'lacute', 'cacute', 'ccedilla', + 'ccaron', 'eacute', 'eogonek', 'edieresis', + 'ecaron', 'iacute', 'icircumflex', 'dcaron', + 'dcroat', 'nacute', 'ncaron', 'oacute', + 'ocircumflex', 'ohungarumlaut', 'odieresis', 'divide', + 'rcaron', 'uring', 'uacute', 'uhungarumlaut', + 'udieresis', 'yacute', 'tcommaaccent', 'dotaccent' + ], +# Baltic + 'ISO-8859-4' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'Aogonek', 'kgreenlandic', 'Rcommaaccent', + 'currency', 'Itilde', 'Lcommaaccent', 'section', + 'dieresis', 'Scaron', 'Emacron', 'Gcommaaccent', + 'Tbar', 'hyphen', 'Zcaron', 'macron', + 'degree', 'aogonek', 'ogonek', 'rcommaaccent', + 'acute', 'itilde', 'lcommaaccent', 'caron', + 'cedilla', 'scaron', 'emacron', 'gcommaaccent', + 'tbar', 'Eng', 'zcaron', 'eng', + 'Amacron', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Iogonek', + 'Ccaron', 'Eacute', 'Eogonek', 'Edieresis', + 'Edotaccent', 'Iacute', 'Icircumflex', 'Imacron', + 'Dcroat', 'Ncommaaccent', 'Omacron', 'Kcommaaccent', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Uogonek', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Utilde', 'Umacron', 'germandbls', + 'amacron', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'iogonek', + 'ccaron', 'eacute', 'eogonek', 'edieresis', + 'edotaccent', 'iacute', 'icircumflex', 'imacron', + 'dcroat', 'ncommaaccent', 'omacron', 'kcommaaccent', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'uogonek', 'uacute', 'ucircumflex', + 'udieresis', 'utilde', 'umacron', 'dotaccent' + ], +# Cyrillic + 'ISO-8859-5' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'afii10023', 'afii10051', 'afii10052', + 'afii10053', 'afii10054', 'afii10055', 'afii10056', + 'afii10057', 'afii10058', 'afii10059', 'afii10060', + 'afii10061', 'hyphen', 'afii10062', 'afii10145', + 'afii10017', 'afii10018', 'afii10019', 'afii10020', + 'afii10021', 'afii10022', 'afii10024', 'afii10025', + 'afii10026', 'afii10027', 'afii10028', 'afii10029', + 'afii10030', 'afii10031', 'afii10032', 'afii10033', + 'afii10034', 'afii10035', 'afii10036', 'afii10037', + 'afii10038', 'afii10039', 'afii10040', 'afii10041', + 'afii10042', 'afii10043', 'afii10044', 'afii10045', + 'afii10046', 'afii10047', 'afii10048', 'afii10049', + 'afii10065', 'afii10066', 'afii10067', 'afii10068', + 'afii10069', 'afii10070', 'afii10072', 'afii10073', + 'afii10074', 'afii10075', 'afii10076', 'afii10077', + 'afii10078', 'afii10079', 'afii10080', 'afii10081', + 'afii10082', 'afii10083', 'afii10084', 'afii10085', + 'afii10086', 'afii10087', 'afii10088', 'afii10089', + 'afii10090', 'afii10091', 'afii10092', 'afii10093', + 'afii10094', 'afii10095', 'afii10096', 'afii10097', + 'afii61352', 'afii10071', 'afii10099', 'afii10100', + 'afii10101', 'afii10102', 'afii10103', 'afii10104', + 'afii10105', 'afii10106', 'afii10107', 'afii10108', + 'afii10109', 'section', 'afii10110', 'afii10193' + ], +# Greek + 'ISO-8859-7' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'quoteleft', 'quoteright', 'sterling', + '.notdef', '.notdef', 'brokenbar', 'section', + 'dieresis', 'copyright', '.notdef', 'guillemotleft', + 'logicalnot', 'hyphen', '.notdef', 'afii00208', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'tonos', 'dieresistonos', 'Alphatonos', 'periodcentered', + 'Epsilontonos', 'Etatonos', 'Iotatonos', 'guillemotright', + 'Omicrontonos', 'onehalf', 'Upsilontonos', 'Omegatonos', + 'iotadieresistonos','Alpha', 'Beta', 'Gamma', + 'Delta', 'Epsilon', 'Zeta', 'Eta', + 'Theta', 'Iota', 'Kappa', 'Lambda', + 'Mu', 'Nu', 'Xi', 'Omicron', + 'Pi', 'Rho', '.notdef', 'Sigma', + 'Tau', 'Upsilon', 'Phi', 'Chi', + 'Psi', 'Omega', 'Iotadieresis', 'Upsilondieresis', + 'alphatonos', 'epsilontonos', 'etatonos', 'iotatonos', + 'upsilondieresistonos','alpha', 'beta', 'gamma', + 'delta', 'epsilon', 'zeta', 'eta', + 'theta', 'iota', 'kappa', 'lambda', + 'mu', 'nu', 'xi', 'omicron', + 'pi', 'rho', 'sigma1', 'sigma', + 'tau', 'upsilon', 'phi', 'chi', + 'psi', 'omega', 'iotadieresis', 'upsilondieresis', + 'omicrontonos', 'upsilontonos', 'omegatonos', '.notdef' + ], +# Turkish + 'ISO-8859-9' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclamdown', 'cent', 'sterling', + 'currency', 'yen', 'brokenbar', 'section', + 'dieresis', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'acute', 'mu', 'paragraph', 'periodcentered', + 'cedilla', 'onesuperior', 'ordmasculine', 'guillemotright', + 'onequarter', 'onehalf', 'threequarters', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Gbreve', 'Ntilde', 'Ograve', 'Oacute', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Idotaccent', 'Scedilla', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'gbreve', 'ntilde', 'ograve', 'oacute', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'dotlessi', 'scedilla', 'ydieresis' + ], +# Thai + 'ISO-8859-11' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'kokaithai', 'khokhaithai', 'khokhuatthai', + 'khokhwaithai', 'khokhonthai', 'khorakhangthai', 'ngonguthai', + 'chochanthai', 'chochingthai', 'chochangthai', 'sosothai', + 'chochoethai', 'yoyingthai', 'dochadathai', 'topatakthai', + 'thothanthai', 'thonangmonthothai','thophuthaothai', 'nonenthai', + 'dodekthai', 'totaothai', 'thothungthai', 'thothahanthai', + 'thothongthai', 'nonuthai', 'bobaimaithai', 'poplathai', + 'phophungthai', 'fofathai', 'phophanthai', 'fofanthai', + 'phosamphaothai', 'momathai', 'yoyakthai', 'roruathai', + 'ruthai', 'lolingthai', 'luthai', 'wowaenthai', + 'sosalathai', 'sorusithai', 'sosuathai', 'hohipthai', + 'lochulathai', 'oangthai', 'honokhukthai', 'paiyannoithai', + 'saraathai', 'maihanakatthai', 'saraaathai', 'saraamthai', + 'saraithai', 'saraiithai', 'sarauethai', 'saraueethai', + 'sarauthai', 'sarauuthai', 'phinthuthai', '.notdef', + '.notdef', '.notdef', '.notdef', 'bahtthai', + 'saraethai', 'saraaethai', 'saraothai', 'saraaimaimuanthai', + 'saraaimaimalaithai','lakkhangyaothai','maiyamokthai', 'maitaikhuthai', + 'maiekthai', 'maithothai', 'maitrithai', 'maichattawathai', + 'thanthakhatthai','nikhahitthai', 'yamakkanthai', 'fongmanthai', + 'zerothai', 'onethai', 'twothai', 'threethai', + 'fourthai', 'fivethai', 'sixthai', 'seventhai', + 'eightthai', 'ninethai', 'angkhankhuthai', 'khomutthai', + '.notdef', '.notdef', '.notdef', '.notdef' + ], +# Western Europe + 'ISO-8859-15' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclamdown', 'cent', 'sterling', + 'Euro', 'yen', 'Scaron', 'section', + 'scaron', 'copyright', 'ordfeminine', 'guillemotleft', + 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', + 'Zcaron', 'mu', 'paragraph', 'periodcentered', + 'zcaron', 'onesuperior', 'ordmasculine', 'guillemotright', + 'OE', 'oe', 'Ydieresis', 'questiondown', + 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', + 'Adieresis', 'Aring', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Eth', 'Ntilde', 'Ograve', 'Oacute', + 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', + 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Yacute', 'Thorn', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', + 'adieresis', 'aring', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'eth', 'ntilde', 'ograve', 'oacute', + 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'yacute', 'thorn', 'ydieresis' + ], +# Central Europe + 'ISO-8859-16' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'Aogonek', 'aogonek', 'Lslash', + 'Euro', 'quotedblbase', 'Scaron', 'section', + 'scaron', 'copyright', 'Scommaaccent', 'guillemotleft', + 'Zacute', 'hyphen', 'zacute', 'Zdotaccent', + 'degree', 'plusminus', 'Ccaron', 'lslash', + 'Zcaron', 'quotedblright', 'paragraph', 'periodcentered', + 'zcaron', 'ccaron', 'scommaaccent', 'guillemotright', + 'OE', 'oe', 'Ydieresis', 'zdotaccent', + 'Agrave', 'Aacute', 'Acircumflex', 'Abreve', + 'Adieresis', 'Cacute', 'AE', 'Ccedilla', + 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', + 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', + 'Dcroat', 'Nacute', 'Ograve', 'Oacute', + 'Ocircumflex', 'Ohungarumlaut', 'Odieresis', 'Sacute', + 'Uhungarumlaut', 'Ugrave', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Eogonek', 'Tcommaaccent', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'abreve', + 'adieresis', 'cacute', 'ae', 'ccedilla', + 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', + 'dcroat', 'nacute', 'ograve', 'oacute', + 'ocircumflex', 'ohungarumlaut', 'odieresis', 'sacute', + 'uhungarumlaut', 'ugrave', 'uacute', 'ucircumflex', + 'udieresis', 'eogonek', 'tcommaaccent', 'ydieresis' + ], +# Russian + 'KOI8-R' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'SF100000', 'SF110000', 'SF010000', 'SF030000', + 'SF020000', 'SF040000', 'SF080000', 'SF090000', + 'SF060000', 'SF070000', 'SF050000', 'upblock', + 'dnblock', 'block', 'lfblock', 'rtblock', + 'ltshade', 'shade', 'dkshade', 'integraltp', + 'filledbox', 'periodcentered', 'radical', 'approxequal', + 'lessequal', 'greaterequal', 'space', 'integralbt', + 'degree', 'twosuperior', 'periodcentered', 'divide', + 'SF430000', 'SF240000', 'SF510000', 'afii10071', + 'SF520000', 'SF390000', 'SF220000', 'SF210000', + 'SF250000', 'SF500000', 'SF490000', 'SF380000', + 'SF280000', 'SF270000', 'SF260000', 'SF360000', + 'SF370000', 'SF420000', 'SF190000', 'afii10023', + 'SF200000', 'SF230000', 'SF470000', 'SF480000', + 'SF410000', 'SF450000', 'SF460000', 'SF400000', + 'SF540000', 'SF530000', 'SF440000', 'copyright', + 'afii10096', 'afii10065', 'afii10066', 'afii10088', + 'afii10069', 'afii10070', 'afii10086', 'afii10068', + 'afii10087', 'afii10074', 'afii10075', 'afii10076', + 'afii10077', 'afii10078', 'afii10079', 'afii10080', + 'afii10081', 'afii10097', 'afii10082', 'afii10083', + 'afii10084', 'afii10085', 'afii10072', 'afii10067', + 'afii10094', 'afii10093', 'afii10073', 'afii10090', + 'afii10095', 'afii10091', 'afii10089', 'afii10092', + 'afii10048', 'afii10017', 'afii10018', 'afii10040', + 'afii10021', 'afii10022', 'afii10038', 'afii10020', + 'afii10039', 'afii10026', 'afii10027', 'afii10028', + 'afii10029', 'afii10030', 'afii10031', 'afii10032', + 'afii10033', 'afii10049', 'afii10034', 'afii10035', + 'afii10036', 'afii10037', 'afii10024', 'afii10019', + 'afii10046', 'afii10045', 'afii10025', 'afii10042', + 'afii10047', 'afii10043', 'afii10041', 'afii10044' + ], +# Ukrainian + 'KOI8-U' => [ + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', + 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quotesingle', + 'parenleft', 'parenright', 'asterisk', 'plus', + 'comma', 'hyphen', 'period', 'slash', + 'zero', 'one', 'two', 'three', + 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'colon', 'semicolon', + 'less', 'equal', 'greater', 'question', + 'at', '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', 'bracketleft', + 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'grave', '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', 'braceleft', + 'bar', 'braceright', 'asciitilde', '.notdef', + 'SF100000', 'SF110000', 'SF010000', 'SF030000', + 'SF020000', 'SF040000', 'SF080000', 'SF090000', + 'SF060000', 'SF070000', 'SF050000', 'upblock', + 'dnblock', 'block', 'lfblock', 'rtblock', + 'ltshade', 'shade', 'dkshade', 'integraltp', + 'filledbox', 'bullet', 'radical', 'approxequal', + 'lessequal', 'greaterequal', 'space', 'integralbt', + 'degree', 'twosuperior', 'periodcentered', 'divide', + 'SF430000', 'SF240000', 'SF510000', 'afii10071', + 'afii10101', 'SF390000', 'afii10103', 'afii10104', + 'SF250000', 'SF500000', 'SF490000', 'SF380000', + 'SF280000', 'afii10098', 'SF260000', 'SF360000', + 'SF370000', 'SF420000', 'SF190000', 'afii10023', + 'afii10053', 'SF230000', 'afii10055', 'afii10056', + 'SF410000', 'SF450000', 'SF460000', 'SF400000', + 'SF540000', 'afii10050', 'SF440000', 'copyright', + 'afii10096', 'afii10065', 'afii10066', 'afii10088', + 'afii10069', 'afii10070', 'afii10086', 'afii10068', + 'afii10087', 'afii10074', 'afii10075', 'afii10076', + 'afii10077', 'afii10078', 'afii10079', 'afii10080', + 'afii10081', 'afii10097', 'afii10082', 'afii10083', + 'afii10084', 'afii10085', 'afii10072', 'afii10067', + 'afii10094', 'afii10093', 'afii10073', 'afii10090', + 'afii10095', 'afii10091', 'afii10089', 'afii10092', + 'afii10048', 'afii10017', 'afii10018', 'afii10040', + 'afii10021', 'afii10022', 'afii10038', 'afii10020', + 'afii10039', 'afii10026', 'afii10027', 'afii10028', + 'afii10029', 'afii10030', 'afii10031', 'afii10032', + 'afii10033', 'afii10049', 'afii10034', 'afii10035', + 'afii10036', 'afii10037', 'afii10024', 'afii10019', + 'afii10046', 'afii10045', 'afii10025', 'afii10042', + 'afii10047', 'afii10043', 'afii10041', 'afii10044' + ] +} + +def ReadAFM(file, map) + + # Read a font metric file + a = IO.readlines(file) + + raise "File no found: #{file}" if a.size == 0 + + widths = {} + fm = {} + fix = { 'Edot' => 'Edotaccent', 'edot' => 'edotaccent', + 'Idot' => 'Idotaccent', + 'Zdot' => 'Zdotaccent', 'zdot' => 'zdotaccent', + 'Odblacute' => 'Ohungarumlaut', 'odblacute' => 'ohungarumlaut', + 'Udblacute' => 'Uhungarumlaut', 'udblacute' => 'uhungarumlaut', + 'Gcedilla' => 'Gcommaaccent', 'gcedilla' => 'gcommaaccent', + 'Kcedilla' => 'Kcommaaccent', 'kcedilla' => 'kcommaaccent', + 'Lcedilla' => 'Lcommaaccent', 'lcedilla' => 'lcommaaccent', + 'Ncedilla' => 'Ncommaaccent', 'ncedilla' => 'ncommaaccent', + 'Rcedilla' => 'Rcommaaccent', 'rcedilla' => 'rcommaaccent', + 'Scedilla' => 'Scommaaccent',' scedilla' => 'scommaaccent', + 'Tcedilla' => 'Tcommaaccent',' tcedilla' => 'tcommaaccent', + 'Dslash' => 'Dcroat', 'dslash' => 'dcroat', + 'Dmacron' => 'Dcroat', 'dmacron' => 'dcroat', + 'combininggraveaccent' => 'gravecomb', + 'combininghookabove' => 'hookabovecomb', + 'combiningtildeaccent' => 'tildecomb', + 'combiningacuteaccent' => 'acutecomb', + 'combiningdotbelow' => 'dotbelowcomb', + 'dongsign' => 'dong' + } + + a.each do |line| + + e = line.rstrip.split(' ') + next if e.size < 2 + + code = e[0] + param = e[1] + + if code == 'C' then + + # Character metrics + cc = e[1].to_i + w = e[4] + gn = e[7] + + gn = 'Euro' if gn[-4, 4] == '20AC' + + if fix[gn] then + + # Fix incorrect glyph name + 0.upto(map.size - 1) do |i| + if map[i] == fix[gn] then + map[i] = gn + end + end + end + + if map.size == 0 then + # Symbolic font: use built-in encoding + widths[cc] = w + else + widths[gn] = w + fm['CapXHeight'] = e[13].to_i if gn == 'X' + end + + fm['MissingWidth'] = w if gn == '.notdef' + + elsif code == 'FontName' then + fm['FontName'] = param + elsif code == 'Weight' then + fm['Weight'] = param + elsif code == 'ItalicAngle' then + fm['ItalicAngle'] = param.to_f + elsif code == 'Ascender' then + fm['Ascender'] = param.to_i + elsif code == 'Descender' then + fm['Descender'] = param.to_i + elsif code == 'UnderlineThickness' then + fm['UnderlineThickness'] = param.to_i + elsif code == 'UnderlinePosition' then + fm['UnderlinePosition'] = param.to_i + elsif code == 'IsFixedPitch' then + fm['IsFixedPitch'] = (param == 'true') + elsif code == 'FontBBox' then + fm['FontBBox'] = "[#{e[1]},#{e[2]},#{e[3]},#{e[4]}]" + elsif code == 'CapHeight' then + fm['CapHeight'] = param.to_i + elsif code == 'StdVW' then + fm['StdVW'] = param.to_i + end + end + + raise 'FontName not found' unless fm['FontName'] + + if map.size > 0 then + widths['.notdef'] = 600 unless widths['.notdef'] + + if (widths['Delta'] == nil) && widths['increment'] then + widths['Delta'] = widths['increment'] + end + + # Order widths according to map + 0.upto(255) do |i| + if widths[map[i]] == nil + puts "Warning: character #{map[i]} is missing" + widths[i] = widths['.notdef'] + else + widths[i] = widths[map[i]] + end + end + end + + fm['Widths'] = widths + + return fm +end + +def MakeFontDescriptor(fm, symbolic) + + # Ascent + asc = fm['Ascender'] ? fm['Ascender'] : 1000 + fd = "{\n 'Ascent' => '#{asc}'" + + # Descent + desc = fm['Descender'] ? fm['Descender'] : -200 + fd += ", 'Descent' => '#{desc}'" + + # CapHeight + if fm['CapHeight'] then + ch = fm['CapHeight'] + elsif fm['CapXHeight'] + ch = fm['CapXHeight'] + else + ch = asc + end + fd += ", 'CapHeight' => '#{ch}'" + + # Flags + flags = 0 + + if fm['IsFixedPitch'] then + flags += 1 << 0 + end + + if symbolic then + flags += 1 << 2 + else + flags += 1 << 5 + end + + if fm['ItalicAngle'] && (fm['ItalicAngle'] != 0) then + flags += 1 << 6 + end + + fd += ",\n 'Flags' => '#{flags}'" + + # FontBBox + if fm['FontBBox'] then + fbb = fm['FontBBox'].gsub(/,/, ' ') + else + fbb = "[0 #{desc - 100} 1000 #{asc + 100}]" + end + + fd += ", 'FontBBox' => '#{fbb}'" + + # ItalicAngle + ia = fm['ItalicAngle'] ? fm['ItalicAngle'] : 0 + fd += ",\n 'ItalicAngle' => '#{ia}'" + + # StemV + if fm['StdVW'] then + stemv = fm['StdVW'] + elsif fm['Weight'] && (/bold|black/i =~ fm['Weight']) + stemv = 120 + else + stemv = 70 + end + + fd += ", 'StemV' => '#{stemv}'" + + # MissingWidth + if fm['MissingWidth'] then + fd += ", 'MissingWidth' => '#{fm['MissingWidth']}'" + end + + fd += "\n }" + return fd +end + +def MakeWidthArray(fm) + + # Make character width array + s = " [\n " + + cw = fm['Widths'] + + 0.upto(255) do |i| + s += "%5d" % cw[i] + s += "," if i != 255 + s += "\n " if (i % 8) == 7 + end + + s += ']' + + return s +end + +def MakeFontEncoding(map) + + # Build differences from reference encoding + ref = Charencodings['cp1252'] + s = '' + last = 0 + 32.upto(255) do |i| + if map[i] != ref[i] then + if i != last + 1 then + s += i.to_s + ' ' + end + last = i + s += '/' + map[i] + ' ' + end + end + return s.rstrip +end + +def ReadShort(f) + a = f.read(2).unpack('n') + return a[0] +end + +def ReadLong(f) + a = f.read(4).unpack('N') + return a[0] +end + +def CheckTTF(file) + + rl = false + pp = false + e = false + + # Check if font license allows embedding + File.open(file, 'rb') do |f| + + # Extract number of tables + f.seek(4, IO::SEEK_CUR) + nb = ReadShort(f) + f.seek(6, IO::SEEK_CUR) + + # Seek OS/2 table + found = false + 0.upto(nb - 1) do |i| + if f.read(4) == 'OS/2' then + found = true + break + end + + f.seek(12, IO::SEEK_CUR) + end + + if ! found then + return + end + + f.seek(4, IO::SEEK_CUR) + offset = ReadLong(f) + f.seek(offset, IO::SEEK_SET) + + # Extract fsType flags + f.seek(8, IO::SEEK_CUR) + fsType = ReadShort(f) + + rl = (fsType & 0x02) != 0 + pp = (fsType & 0x04) != 0 + e = (fsType & 0x08) != 0 + end + + if rl && ( ! pp) && ( ! e) then + puts 'Warning: font license does not allow embedding' + end +end + +# +# fontfile: path to TTF file (or empty string if not to be embedded) +# afmfile: path to AFM file +# enc: font encoding (or empty string for symbolic fonts) +# patch: optional patch for encoding +# type : font type if $fontfile is empty +# +def MakeFont(fontfile, afmfile, enc = 'cp1252', patch = {}, type = 'TrueType') + # Generate a font definition file + if (enc != nil) && (enc != '') then + map = Charencodings[enc] + patch.each { |cc, gn| map[cc] = gn } + else + map = [] + end + + raise "Error: AFM file not found: #{afmfile}" unless File.exists?(afmfile) + + fm = ReadAFM(afmfile, map) + + if (enc != nil) && (enc != '') then + diff = MakeFontEncoding(map) + else + diff = '' + end + + fd = MakeFontDescriptor(fm, (map.size == 0)) + + # Find font type + if fontfile then + ext = File.extname(fontfile).downcase.sub(/^\./, '') + + if ext == 'ttf' then + type = 'TrueType' + elsif ext == 'pfb' + type = 'Type1' + else + raise "Error: unrecognized font file extension: #{ext}" + end + else + raise "Error: incorrect font type: #{type}" if (type != 'TrueType') && (type != 'Type1') + end + printf "type = #{type}\n" + # Start generation + s = "# #{fm['FontName']} font definition\n\n" + s += "module FontDef\n" + s += " def FontDef.type\n '#{type}'\n end\n" + s += " def FontDef.name\n '#{fm['FontName']}'\n end\n" + s += " def FontDef.desc\n #{fd}\n end\n" + + if fm['UnderlinePosition'] == nil then + fm['UnderlinePosition'] = -100 + end + + if fm['UnderlineThickness'] == nil then + fm['UnderlineThickness'] = 50 + end + + s += " def FontDef.up\n #{fm['UnderlinePosition']}\n end\n" + s += " def FontDef.ut\n #{fm['UnderlineThickness']}\n end\n" + + w = MakeWidthArray(fm) + s += " def FontDef.cw\n#{w}\n end\n" + + s += " def FontDef.enc\n '#{enc}'\n end\n" + s += " def FontDef.diff\n #{(diff == nil) || (diff == '') ? 'nil' : '\'' + diff '\''}\n end\n" + + basename = File.basename(afmfile, '.*') + + if fontfile then + # Embedded font + if ! File.exist?(fontfile) then + raise "Error: font file not found: #{fontfile}" + end + + if type == 'TrueType' then + CheckTTF(fontfile) + end + + file = '' + File.open(fontfile, 'rb') do |f| + file = f.read() + end + + if type == 'Type1' then + # Find first two sections and discard third one + header = file[0] == 128 + file = file[6, file.length - 6] if header + + pos = file.index('eexec') + raise 'Error: font file does not seem to be valid Type1' if pos == nil + + size1 = pos + 6 + + file = file[0, size1] + file[size1 + 6, file.length - (size1 + 6)] if header && file[size1] == 128 + + pos = file.index('00000000') + raise 'Error: font file does not seem to be valid Type1' if pos == nil + + size2 = pos - size1 + file = file[0, size1 + size2] + end + + if require 'zlib' then + File.open(basename + '.z', 'wb') { |f| f.write(Zlib::Deflate.deflate(file)) } + s += " def FontDef.file\n '#{basename}.z'\n end\n" + puts "Font file compressed ('#{basename}.z')" + else + s += " def FontDef.file\n '#{File.basename(fontfile)}'\n end\n" + puts 'Notice: font file could not be compressed (zlib not available)' + end + + if type == 'Type1' then + s += " def FontDef.size1\n '#{size1}'\n end\n" + s += " def FontDef.size2\n '#{size2}'\n end\n" + else + s += " def FontDef.originalsize\n '#{File.size(fontfile)}'\n end\n" + end + + else + # Not embedded font + s += " def FontDef.file\n ''\n end\n" + end + + s += "end\n" + File.open(basename + '.rb', 'w') { |file| file.write(s)} + puts "Font definition file generated (#{basename}.rb)" +end + + +if $0 == __FILE__ then + if ARGV.length >= 3 then + enc = ARGV[2] + else + enc = 'cp1252' + end + + if ARGV.length >= 4 then + patch = ARGV[3] + else + patch = {} + end + + if ARGV.length >= 5 then + type = ARGV[4] + else + type = 'TrueType' + end + + MakeFont(ARGV[0], ARGV[1], enc, patch, type) +end diff --git a/lib/plugins/rfpdf/lib/rfpdf.rb b/lib/plugins/rfpdf/lib/rfpdf.rb new file mode 100644 index 000000000..e57679d54 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf.rb @@ -0,0 +1,40 @@ +# Copyright (c) 2006 4ssoM LLC +# +# 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. + +require 'action_controller' +require 'action_view' + +require 'rfpdf/action_controller' +require 'rfpdf/action_view' + +require 'rfpdf/template_handler/compile_support' + +require 'rfpdf/template_handlers/base' + + +class ActionController::Base + include RFPDF::ActionController +end + +class ActionView::Base + include RFPDF::ActionView +end diff --git a/lib/plugins/rfpdf/lib/rfpdf/action_controller.rb b/lib/plugins/rfpdf/lib/rfpdf/action_controller.rb new file mode 100644 index 000000000..905fc7045 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/action_controller.rb @@ -0,0 +1,40 @@ +module RFPDF + module ActionController + + DEFAULT_RFPDF_OPTIONS = {:inline=>true} + + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + def rfpdf(options) + rfpdf_options = breakdown_rfpdf_options options + write_inheritable_hash(:rfpdf, rfpdf_options) + end + + private + + def breakdown_rfpdf_options(options) + rfpdf_options = options.dup + rfpdf_options + end + end + + def rfpdf(options) + @rfpdf_options ||= DEFAULT_RFPDF_OPTIONS.dup + @rfpdf_options.merge! options + end + + + private + + def compute_rfpdf_options + @rfpdf_options ||= DEFAULT_RFPDF_OPTIONS.dup + @rfpdf_options.merge!(self.class.read_inheritable_attribute(:rfpdf) || {}) {|k,o,n| o} + @rfpdf_options + end + end +end + + diff --git a/lib/plugins/rfpdf/lib/rfpdf/action_view.rb b/lib/plugins/rfpdf/lib/rfpdf/action_view.rb new file mode 100644 index 000000000..9836472d1 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/action_view.rb @@ -0,0 +1,12 @@ +module RFPDF + module ActionView + + private + def _rfpdf_compile_setup(dsl_setup = false) + compile_support = RFPDF::TemplateHandler::CompileSupport.new(controller) + @rfpdf_options = compile_support.options + end + + end +end + diff --git a/lib/plugins/rfpdf/lib/rfpdf/errors.rb b/lib/plugins/rfpdf/lib/rfpdf/errors.rb new file mode 100644 index 000000000..b1bc068b8 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/errors.rb @@ -0,0 +1,6 @@ +module RFPDF + module Errors + class GenerationError < StandardError #:nodoc: + end + end +end \ No newline at end of file diff --git a/lib/plugins/rfpdf/lib/rfpdf/fpdf.rb b/lib/plugins/rfpdf/lib/rfpdf/fpdf.rb new file mode 100644 index 000000000..37c6d9443 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/fpdf.rb @@ -0,0 +1,1632 @@ +# Ruby FPDF 1.53d +# FPDF 1.53 by Olivier Plathey ported to Ruby by Brian Ollenberger +# Copyright 2005 Brian Ollenberger +# Please retain this entire copyright notice. If you distribute any +# modifications, place an additional comment here that clearly indicates +# that it was modified. You may (but are not send any useful modifications that you make +# back to me at http://zeropluszero.com/software/fpdf/ + +# Bug fixes, examples, external fonts, JPEG support, and upgrade to version +# 1.53 contributed by Kim Shrier. +# +# Bookmark support contributed by Sylvain Lafleur. +# +# EPS support contributed by Thiago Jackiw, ported from the PHP version by Valentin Schmidt. +# +# Bookmarks contributed by Sylvain Lafleur. +# +# 1.53 contributed by Ed Moss +# Make sure all \n references are inside double quotes - Fix some multicell bugs +# Handle "\n" at the beginning of a string +# Bookmarks contributed by Sylvain Lafleur. + +require 'date' +require 'zlib' + +class FPDF + include RFPDF + + attr_accessor :default_font + + FPDF_VERSION = '1.53d' + + Charwidths = { + 'courier'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], + + 'courierB'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], + + 'courierI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], + + 'courierBI'=>[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600], + + 'helvetica'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500], + + 'helveticaB'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556], + + 'helveticaI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 350, 556, 350, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500], + + 'helveticaBI'=>[278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 350, 556, 350, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 350, 611, 350, 350, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 350, 500, 667, 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556], + + 'times'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 408, 500, 500, 833, 778, 180, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 350, 500, 350, 333, 500, 444, 1000, 500, 500, 333, 1000, 556, 333, 889, 350, 611, 350, 350, 333, 333, 444, 444, 350, 500, 1000, 333, 980, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 200, 500, 333, 760, 276, 500, 564, 333, 760, 333, 400, 564, 300, 300, 333, 500, 453, 250, 333, 300, 310, 500, 750, 750, 750, 444, 722, 722, 722, 722, 722, 722, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 722, 722, 722, 722, 722, 722, 564, 722, 722, 722, 722, 722, 722, 556, 500, 444, 444, 444, 444, 444, 444, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 564, 500, 500, 500, 500, 500, 500, 500, 500], + + 'timesB'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 555, 500, 500, 1000, 833, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 1000, 350, 667, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 444, 722, 250, 333, 500, 500, 500, 500, 220, 500, 333, 747, 300, 500, 570, 333, 747, 333, 400, 570, 300, 300, 333, 556, 540, 250, 333, 300, 330, 500, 750, 750, 750, 500, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 778, 778, 778, 778, 778, 570, 778, 722, 722, 722, 722, 722, 611, 556, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 500, 556, 500], + + 'timesI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 420, 500, 500, 833, 778, 214, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 350, 500, 350, 333, 500, 556, 889, 500, 500, 333, 1000, 500, 333, 944, 350, 556, 350, 350, 333, 333, 556, 556, 350, 500, 889, 333, 980, 389, 333, 667, 350, 389, 556, 250, 389, 500, 500, 500, 500, 275, 500, 333, 760, 276, 500, 675, 333, 760, 333, 400, 675, 300, 300, 333, 500, 523, 250, 333, 300, 310, 500, 750, 750, 750, 500, 611, 611, 611, 611, 611, 611, 889, 667, 611, 611, 611, 611, 333, 333, 333, 333, 722, 667, 722, 722, 722, 722, 722, 675, 722, 722, 722, 722, 722, 556, 611, 500, 500, 500, 500, 500, 500, 500, 667, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 500, 500, 500, 500, 500, 500, 675, 500, 500, 500, 500, 500, 444, 500, 444], + + 'timesBI'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 389, 555, 500, 500, 833, 778, 278, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 350, 500, 350, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 944, 350, 611, 350, 350, 333, 333, 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 350, 389, 611, 250, 389, 500, 500, 500, 500, 220, 500, 333, 747, 266, 500, 606, 333, 747, 333, 400, 570, 300, 300, 333, 576, 500, 250, 333, 300, 300, 500, 750, 750, 750, 500, 667, 667, 667, 667, 667, 667, 944, 667, 667, 667, 667, 667, 389, 389, 389, 389, 722, 722, 722, 722, 722, 722, 722, 570, 722, 722, 722, 722, 722, 611, 611, 500, 500, 500, 500, 500, 500, 500, 722, 444, 444, 444, 444, 444, 278, 278, 278, 278, 500, 556, 500, 500, 500, 500, 500, 570, 500, 556, 556, 556, 556, 444, 500, 444], + + 'symbol'=>[250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645, 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 750, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494, 0, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, 0], + + 'zapfdingbats'=>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 0, 390, 390, 317, 317, 276, 276, 509, 509, 410, 410, 234, 234, 334, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 0, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, 0] + } + + def initialize(orientation='P', unit='mm', format='A4') + # Initialization of properties + @page=0 + @n=2 + @buffer='' + @pages=[] + @OrientationChanges=[] + @state=0 + @default_font = "arial" + @fonts={} + @FontFiles={} + @diffs=[] + @images={} + @links=[] + @PageLinks={} + @InFooter=false + @FontFamily='' + @FontStyle='' + @FontSizePt=12 + @underline= false + @DrawColor='0 G' + @FillColor='0 g' + @TextColor='0 g' + @ColorFlag=false + @ws=0 + @offsets=[] + + # Standard fonts + @CoreFonts={} + @CoreFonts['courier']='Courier' + @CoreFonts['courierB']='Courier-Bold' + @CoreFonts['courierI']='Courier-Oblique' + @CoreFonts['courierBI']='Courier-BoldOblique' + @CoreFonts['helvetica']='Helvetica' + @CoreFonts['helveticaB']='Helvetica-Bold' + @CoreFonts['helveticaI']='Helvetica-Oblique' + @CoreFonts['helveticaBI']='Helvetica-BoldOblique' + @CoreFonts['times']='Times-Roman' + @CoreFonts['timesB']='Times-Bold' + @CoreFonts['timesI']='Times-Italic' + @CoreFonts['timesBI']='Times-BoldItalic' + @CoreFonts['symbol']='Symbol' + @CoreFonts['zapfdingbats']='ZapfDingbats' + + # Scale factor + if unit=='pt' + @k=1 + elsif unit=='mm' + @k=72/25.4 + elsif unit=='cm' + @k=72/2.54; + elsif unit=='in' + @k=72 + else + raise 'Incorrect unit: '+unit + end + + # Page format + if format.is_a? String + format.downcase! + if format=='a3' + format=[841.89,1190.55] + elsif format=='a4' + format=[595.28,841.89] + elsif format=='a5' + format=[420.94,595.28] + elsif format=='letter' + format=[612,792] + elsif format=='legal' + format=[612,1008] + else + raise 'Unknown page format: '+format + end + @fwPt,@fhPt=format + else + @fwPt=format[0]*@k + @fhPt=format[1]*@k + end + @fw=@fwPt/@k; + @fh=@fhPt/@k; + + # Page orientation + orientation.downcase! + if orientation=='p' or orientation=='portrait' + @DefOrientation='P' + @wPt=@fwPt + @hPt=@fhPt + elsif orientation=='l' or orientation=='landscape' + @DefOrientation='L' + @wPt=@fhPt + @hPt=@fwPt + else + raise 'Incorrect orientation: '+orientation + end + @CurOrientation=@DefOrientation + @w=@wPt/@k + @h=@hPt/@k + + # Page margins (1 cm) + margin=28.35/@k + SetMargins(margin,margin) + # Interior cell margin (1 mm) + @cMargin=margin/10 + # Line width (0.2 mm) + @LineWidth=0.567/@k + # Automatic page break + SetAutoPageBreak(true,2*margin) + # Full width display mode + SetDisplayMode('fullwidth') + # Enable compression + SetCompression(true) + # Set default PDF version number + @PDFVersion='1.3' + end + + def GetMargins() + return @lMargin, @tMargin, @rMargin + end + + def SetMargins(left, top, right=-1) + # Set left, top and right margins + @lMargin=left + @tMargin=top + right=left if right==-1 + @rMargin=right + end + + def SetLeftMargin(margin) + # Set left margin + @lMargin=margin + @x=margin if @page>0 and @x0 + # Page footer + @InFooter=true + self.Footer + @InFooter=false + # Close page + endpage + end + # Start new page + beginpage(orientation) + # Set line cap style to square + out('2 J') + # Set line width + @LineWidth=lw + out(sprintf('%.2f w',lw*@k)) + # Set font + SetFont(family,style,size) if family + # Set colors + @DrawColor=dc + out(dc) if dc!='0 G' + @FillColor=fc + out(fc) if fc!='0 g' + @TextColor=tc + @ColorFlag=cf + # Page header + self.Header + # Restore line width + if @LineWidth!=lw + @LineWidth=lw + out(sprintf('%.2f w',lw*@k)) + end + # Restore font + self.SetFont(family,style,size) if family + # Restore colors + if @DrawColor!=dc + @DrawColor=dc + out(dc) + end + if @FillColor!=fc + @FillColor=fc + out(fc) + end + @TextColor=tc + @ColorFlag=cf + end + alias_method :add_page, :AddPage + + def Header + # To be implemented in your inherited class + end + + def Footer + # To be implemented in your inherited class + end + + def PageNo + # Get current page number + @page + end + + 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 + @DrawColor=sprintf('%.3f G',r/255.0) + else + @DrawColor=sprintf('%.3f %.3f %.3f RG',r/255.0,g/255.0,b/255.0) + end + out(@DrawColor) if(@page>0) + end + + def SetFillColor(r,g=-1,b=-1) + # Set color for all filling operations + if (r==0 and g==0 and b==0) or g==-1 + @FillColor=sprintf('%.3f g',r/255.0) + else + @FillColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) + end + @ColorFlag=(@FillColor!=@TextColor) + out(@FillColor) if(@page>0) + end + + def SetTextColor(r,g=-1,b=-1) + # Set color for text + if (r==0 and g==0 and b==0) or g==-1 + @TextColor=sprintf('%.3f g',r/255.0) + else + @TextColor=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) + end + @ColorFlag=(@FillColor!=@TextColor) + end + + def GetCharWidth(widths, index) + if index.is_a?(String) + widths[index.ord] + else + widths[index] + end + end + + def GetStringWidth(s) + # Get width of a string in the current font + cw=@CurrentFont['cw'] + w=0 + s.each_byte do |c| + w=w+GetCharWidth(cw, c) + end + w*@FontSize/1000.0 + end + + def SetLineWidth(width) + # Set line width + @LineWidth=width + out(sprintf('%.2f w',width*@k)) if @page>0 + end + + 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 + + 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 + + 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 + # x y width height re + out(sprintf('%.2f %.2f %.2f %.2f re %s', x*@k,(@h-y)*@k,w*@k,-h*@k,op)) + end + + def AddFont(family, style='', file='') + # Add a TrueType or Type1 font + family = family.downcase + family = 'helvetica' if family == 'arial' + + style = style.upcase + style = 'BI' if style == 'IB' + + fontkey = family + style + + if @fonts.has_key?(fontkey) + self.Error("Font already added: #{family} #{style}") + end + + file = family.gsub(' ', '') + style.downcase + '.rb' if file == '' + + if self.class.const_defined? 'FPDF_FONTPATH' + if FPDF_FONTPATH[-1,1] == '/' + file = FPDF_FONTPATH + file + else + file = FPDF_FONTPATH + '/' + file + end + end + + # Changed from "require file" to fix bug reported by Hans Allis. + load file + + if FontDef.desc.nil? + self.Error("Could not include font definition file #{file}") + end + + i = @fonts.length + 1 + + @fonts[fontkey] = {'i' => i, + 'type' => FontDef.type, + 'name' => FontDef.name, + 'desc' => FontDef.desc, + 'up' => FontDef.up, + 'ut' => FontDef.ut, + 'cw' => FontDef.cw, + 'enc' => FontDef.enc, + 'file' => FontDef.file + } + + if FontDef.diff + # Search existing encodings + unless @diffs.include?(FontDef.diff) + @diffs.push(FontDef.diff) + @fonts[fontkey]['diff'] = @diffs.length - 1 + end + end + + if FontDef.file + if FontDef.type == 'TrueType' + @FontFiles[FontDef.file] = {'length1' => FontDef.originalsize} + else + @FontFiles[FontDef.file] = {'length1' => FontDef.size1, 'length3' => FontDef.size2} + end + end + + return self + end + + def SetFont(family, style='', size=0) + # Select a font; size given in points + family.downcase! + family=@FontFamily if family=='' + if family=='arial' + family='helvetica' + elsif family=='symbol' or family=='zapfdingbats' + style='' + end + style.upcase! + unless style.index('U').nil? + @underline=true + style.gsub!('U','') + else + @underline=false; + end + style='BI' if style=='IB' + size=@FontSizePt if size==0 + # Test if font is already selected + return if @FontFamily==family and + @FontStyle==style and @FontSizePt==size + # Test if used for the first time + fontkey=family+style + unless @fonts.has_key?(fontkey) + if @CoreFonts.has_key?(fontkey) + unless Charwidths.has_key?(fontkey) + raise 'Font unavailable' + end + @fonts[fontkey]={ + 'i'=>@fonts.size, + 'type'=>'core', + 'name'=>@CoreFonts[fontkey], + 'up'=>-100, + 'ut'=>50, + 'cw'=>Charwidths[fontkey]} + else + raise 'Font unavailable' + end + end + + #Select it + @FontFamily=family + @FontStyle=style; + @FontSizePt=size + @FontSize=size/@k; + @CurrentFont=@fonts[fontkey] + if @page>0 + out(sprintf('BT /F%d %.2f Tf ET', @CurrentFont['i'], @FontSizePt)) + end + end + + def SetFontSize(size) + # Set font size in points + return if @FontSizePt==size + @FontSizePt=size + @FontSize=size/@k + if @page>0 + out(sprintf('BT /F%d %.2f Tf ET',@CurrentFont['i'],@FontSizePt)) + end + end + + def AddLink + # Create a new internal link + @links.push([0, 0]) + @links.size + end + + def SetLink(link, y=0, page=-1) + # Set destination of internal link + y=@y if y==-1 + page=@page if page==-1 + @links[link]=[page, y] + end + + def Link(x, y, w, h, link) + # Put a link on the page + @PageLinks[@page]=Array.new unless @PageLinks.has_key?(@Page) + @PageLinks[@page].push([x*@k,@hPt-y*@k,w*@k,h*@k,link]) + end + + def Text(x, y, txt) + # Output a string + s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*@k,(@h-y)*@k, escape(txt)); + s=s+' '+dounderline(x,y,txt) if @underline and txt!='' + s='q '+@TextColor+' '+s+' Q' if @ColorFlag + out(s) + end + + def AcceptPageBreak + # Accept automatic page break or not + @AutoPageBreak + end + + def BreakThePage?(h) + if (@y + h) > @PageBreakTrigger and !@InFooter and self.AcceptPageBreak + true + else + false + end + end + + def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='') + # Output a cell + if self.BreakThePage?(h) + # Automatic page break + x=@x + ws=@ws + if ws>0 + @ws=0 + out('0 Tw') + end + self.AddPage(@CurOrientation) + @x=x + if ws>0 + @ws=ws + out(sprintf('%.3f Tw',ws*@k)) + end + end + w=@w-@rMargin-@x if w==0 + s='' + if fill==1 or border==1 + if fill==1 + op=(border==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 + unless border.index('L').nil? + s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', + x*@k,(@h-y)*@k,x*@k,(@h-(y+h))*@k) + end + unless border.index('T').nil? + s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', + x*@k,(@h-y)*@k,(x+w)*@k,(@h-y)*@k) + end + unless border.index('R').nil? + s=s+sprintf('%.2f %.2f m %.2f %.2f l S ', + (x+w)*@k,(@h-y)*@k,(x+w)*@k,(@h-(y+h))*@k) + end + unless border.index('B').nil? + s=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!='' + if align=='R' + dx=w-@cMargin-self.GetStringWidth(txt) + elsif align=='C' + dx=(w-self.GetStringWidth(txt))/2 + else + dx=@cMargin + end + if @ColorFlag + s=s+'q '+@TextColor+' ' + end + s=s+sprintf('BT %.2f %.2f Td (%s) Tj ET', + (@x+dx)*@k,(@h-(@y+0.5*h+0.3*@FontSize))*@k,escape(txt)) + s=s+' '+dounderline(@x+dx,@y+0.5*h+0.3*@FontSize,txt) if @underline + s=s+' Q' if @ColorFlag + if link and link != '' + Link(@x+dx,@y+0.5*h-0.5*@FontSize,GetStringWidth(txt),@FontSize,link) + end + end + out(s) if s + @lasth=h + if ln>0 + # Go to next line + @y=@y+h + @x=@lMargin if ln==1 + else + @x=@x+w + end + end + + def MultiCell(w,h,txt,border=0,align='J',fill=0) + # Output text with automatic or explicit line breaks + cw=@CurrentFont['cw'] + w=@w-@rMargin-@x if w==0 + wmax=(w-2*@cMargin)*1000/@FontSize + s=txt.gsub("\r",'') + nb=s.length + nb=nb-1 if nb>0 and s[nb-1].chr=="\n" + b=0 + if border!=0 + if border==1 + border='LTRB' + b='LRT' + b2='LR' + else + b2='' + b2='L' unless border.index('L').nil? + b2=b2+'R' unless border.index('R').nil? + b=(not border.index('T').nil?) ? (b2+'T') : b2 + end + end + sep=-1 + to_index=0 + from_j=0 + l=0 + ns=0 + nl=1 + while to_index0 + @ws=0 + out('0 Tw') + end +#Ed Moss + end_i = to_index == 0 ? 0 : to_index - 1 + # Changed from s[from_j..to_index] to fix bug reported by Hans Allis. + self.Cell(w,h,s[from_j..end_i],b,2,align,fill) +# + to_index=to_index+1 + sep=-1 + from_j=to_index + l=0 + ns=0 + nl=nl+1 + b=b2 if border and nl==2 + else + if char==' '[0] + sep=to_index + ls=l + ns=ns+1 + end + l=l+GetCharWidth(cw, char) + if l>wmax + # Automatic line break + if sep==-1 + to_index=to_index+1 if to_index==from_j + if @ws>0 + @ws=0 + out('0 Tw') + end +#Ed Moss + self.Cell(w,h,s[from_j..to_index-1],b,2,align,fill) +# + else + if align=='J' + @ws=(ns>1) ? (wmax-ls)/1000.0*@FontSize/(ns-1) : 0 + out(sprintf('%.3f Tw',@ws*@k)) + end + self.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=nl+1 + b=b2 if border and nl==2 + else + to_index=to_index+1 + end + end + end + + # Last chunk + if @ws>0 + @ws=0 + out('0 Tw') + end + b=b+'B' if border!=0 and not border.index('B').nil? + self.Cell(w,h,s[from_j..to_index],b,2,align,fill) + @x=@lMargin + end + + def Write(h,txt,link='') + # Output text in flowing mode + cw=@CurrentFont['cw'] + w=@w-@rMargin-@x + wmax=(w-2*@cMargin)*1000/@FontSize + s=txt.gsub("\r",'') + nb=s.length + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while iwmax + # Automatic line break + if sep==-1 + if @x>@lMargin + # Move to next line + @x=@lMargin + @y=@y+h + w=@w-@rMargin-@x + wmax=(w-2*@cMargin)*1000/@FontSize + i=i+1 + nl=nl+1 + next + end + i=i+1 if i==j + self.Cell(w,h,s[j,i-j],0,2,'',0,link) + else + self.Cell(w,h,s[j,sep-j],0,2,'',0,link) + i=sep+1 + end + sep=-1 + j=i + l=0 + if nl==1 + @x=@lMargin + w=@w-@rMargin-@x + wmax=(w-2*@cMargin)*1000/@FontSize + end + nl=nl+1 + else + i=i+1 + end + end + # Last chunk + self.Cell(l/1000.0*@FontSize,h,s[j,i],0,0,'',0,link) if i!=j + end + + def Image(file,x,y,w=0,h=0,type='',link='') + # Put an image on the page + unless @images.has_key?(file) + # First use of image, get info + if type=='' + pos=file.rindex('.') + if pos.nil? + self.Error('Image file has no extension and no type was '+ + 'specified: '+file) + end + type=file[pos+1..-1] + end + type.downcase! + if type=='jpg' or type=='jpeg' + info=parsejpg(file) + elsif type=='png' + info=parsepng(file) + else + self.Error('Unsupported image file type: '+type) + end + info['i']=@images.length+1 + @images[file]=info + else + info=@images[file] + end +#Ed Moss + if(w==0 && h==0) + #Put image at 72 dpi + w=info['w']/@k; + h=info['h']/@k; + end +# + # Automatic width or height calculation + w=h*info['w']/info['h'] if w==0 + h=w*info['h']/info['w'] if h==0 + 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'])) + Link(x,y,w,h,link) if link and link != '' + end + + def Ln(h='') + # Line feed; default value is last cell height + @x=@lMargin + if h.kind_of?(String) + @y=@y+@lasth + else + @y=@y+h + end + end + + def GetX + # Get x position + @x + end + + def SetX(x) + # Set x position + if x>=0 + @x=x + else + @x=@w+x + end + end + + def GetY + # Get y position + @y + end + + def SetY(y) + # Set y position and reset x + @x=@lMargin + if y>=0 + @y=y + else + @y=@h+y + end + end + + def SetXY(x,y) + # Set x and y positions + SetY(y) + SetX(x) + end + + def Output(file=nil) + # Output PDF to file or return as a string + + # Finish document if necessary + self.Close if(@state<3) + + if file.nil? + # Return as a string + return @buffer + else + # Save file locally + open(file,'wb') do |f| + f.write(@buffer) + end + end + end + + private + + def putpages + nb=@page + unless @AliasNbPages.nil? or @AliasNbPages=='' + # Replace number of pages + 1.upto(nb) do |n| + @pages[n].gsub!(@AliasNbPages,nb.to_s) + end + end + if @DefOrientation=='P' + wPt=@fwPt + hPt=@fhPt + else + wPt=@fhPt + hPt=@fwPt + end + filter=(@compress) ? '/Filter /FlateDecode ' : '' + 1.upto(nb) do |n| + # Page + newobj + out('<>>>' + else + l=@links[pl[4]] + h=@OrientationChanges[l[0]].nil? ? hPt : wPt + annots=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) ? Zlib::Deflate.deflate(@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('<>') + out('endobj') + end + + def putfonts + nf=@n + @diffs.each do |diff| + # Encodings + newobj + out('<>') + out('endobj') + end + + @FontFiles.each do |file, info| + # Font file embedding + newobj + @FontFiles[file]['n'] = @n + + if self.class.const_defined? 'FPDF_FONTPATH' then + if FPDF_FONTPATH[-1,1] == '/' then + file = FPDF_FONTPATH + file + else + file = FPDF_FONTPATH + '/' + file + end + end + + size = File.size(file) + unless File.exists?(file) + Error('Font file not found') + end + + out('<>') + open(file, 'rb') do |f| + putstream(f.read()) + end + out('endobj') + end + + file = 0 + @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('<>') + out('endobj') + elsif type=='Type1' or type=='TrueType' + # Additional Type1 or TrueType font + newobj + out('<>') + out('endobj') + # Widths + newobj + cw=font['cw'] + s='[' + 32.upto(255) do |i| + s << GetCharWidth(cw, i).to_s + ' ' + end + out(s+']') + out('endobj') + # Descriptor + newobj + s='<>') + out('endobj') + else + # Allow for additional types + mtd='put'+type.downcase + unless self.respond_to?(mtd) + self.Error('Unsupported font type: '+type) + end + self.send(mtd, font) + end + end + end + + def putimages + filter=(@compress) ? '/Filter /FlateDecode ' : '' + @images.each do |file, info| + newobj + @images[file]['n']=@n + out('<>') + putstream(info['data']) + @images[file]['data']=nil + out('endobj') + # Palette + if info['cs']=='Indexed' + newobj + pal=(@compress) ? Zlib::Deflate.deflate(info['pal']) : info['pal'] + out('<<'+filter+'/Length '+pal.length.to_s+'>>') + putstream(pal) + out('endobj') + end + end + end + + def putxobjectdict + @images.each_value do |image| + out('/I'+image['i'].to_s+' '+image['n'].to_s+' 0 R') + end + end + + 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 + + def putresources + putfonts + putimages + # Resource dictionary + @offsets[2]=@buffer.length + out('2 0 obj') + out('<<') + putresourcedict + out('>>') + out('endobj') + end + + def putinfo + out('/Producer '+textstring('Ruby FPDF '+FPDF_VERSION)); + unless @title.nil? + out('/Title '+textstring(@title)) + end + unless @subject.nil? + out('/Subject '+textstring(@subject)) + end + unless @author.nil? + out('/Author '+textstring(@author)) + end + unless @keywords.nil? + out('/Keywords '+textstring(@keywords)) + end + unless @creator.nil? + out('/Creator '+textstring(@creator)) + end + out('/CreationDate '+textstring('D: '+DateTime.now.to_s)) + end + + def putcatalog + out('/Type /Catalog') + out('/Pages 1 0 R') + if @ZoomMode=='fullpage' + out('/OpenAction [3 0 R /Fit]') + elsif @ZoomMode=='fullwidth' + out('/OpenAction [3 0 R /FitH null]') + elsif @ZoomMode=='real' + out('/OpenAction [3 0 R /XYZ null null 1]') + elsif not @ZoomMode.kind_of?(String) + out('/OpenAction [3 0 R /XYZ null null '+(@ZoomMode/100)+']') + end + + if @LayoutMode=='single' + out('/PageLayout /SinglePage') + elsif @LayoutMode=='continuous' + out('/PageLayout /OneColumn') + elsif @LayoutMode=='two' + out('/PageLayout /TwoColumnLeft') + end + end + + def putheader + out('%PDF-'+@PDFVersion) + end + + def puttrailer + out('/Size '+(@n+1).to_s) + out('/Root '+@n.to_s+' 0 R') + out('/Info '+(@n-1).to_s+' 0 R') + end + + 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 + + def beginpage(orientation) + @page=@page+1 + @pages[@page]='' + @state=2 + @x=@lMargin + @y=@tMargin + @lasth=0 + @FontFamily='' + # Page orientation + if orientation=='' + orientation=@DefOrientation + else + orientation=orientation[0].chr.upcase + if orientation!=@DefOrientation + @OrientationChanges[@page]=true + end + end + if orientation!=@CurOrientation + # Change orientation + if orientation=='P' + @wPt=@fwPt + @hPt=@fhPt + @w=@fw + @h=@fh + else + @wPt=@fhPt + @hPt=@fwPt + @w=@fh + @h=@fw + end + @PageBreakTrigger=@h-@bMargin + @CurOrientation=orientation + end + end + + def endpage + # End of page contents + @state=1 + end + + def newobj + # Begin a new object + @n=@n+1 + @offsets[@n]=@buffer.length + out(@n.to_s+' 0 obj') + end + + def dounderline(x,y,txt) + # Underline text + up=@CurrentFont['up'] + ut=@CurrentFont['ut'] + w=GetStringWidth(txt)+@ws*txt.count(' ') + sprintf('%.2f %.2f %.2f %.2f re f', + x*@k,(@h-(y-up/1000.0*@FontSize))*@k,w*@k,-ut/1000.0*@FontSizePt) + end + + def parsejpg(file) + # Extract info from a JPEG file + a=extractjpginfo(file) + raise "Missing or incorrect JPEG file: #{file}" if a.nil? + + if a['channels'].nil? || a['channels']==3 then + colspace='DeviceRGB' + elsif a['channels']==4 then + colspace='DeviceCMYK' + else + colspace='DeviceGray' + end + bpc= a['bits'] ? a['bits'].to_i : 8 + + # Read whole file + data = nil + open(file, 'rb') do |f| + data = f.read + end + return {'w'=>a['width'],'h'=>a['height'],'cs'=>colspace,'bpc'=>bpc,'f'=>'DCTDecode','data'=>data} + end + + def parsepng(file) + # Extract info from a PNG file + f=open(file,'rb') + # Check signature + unless f.read(8)==137.chr+'PNG'+13.chr+10.chr+26.chr+10.chr + self.Error('Not a PNG file: '+file) + end + # Read header chunk + f.read(4) + if f.read(4)!='IHDR' + self.Error('Incorrect PNG file: '+file) + end + w=freadint(f) + h=freadint(f) + bpc=f.read(1)[0] + if bpc>8 + self.Error('16-bit depth not supported: '+file) + end + ct=f.read(1)[0] + if ct==0 + colspace='DeviceGray' + elsif ct==2 + colspace='DeviceRGB' + elsif ct==3 + colspace='Indexed' + else + self.Error('Alpha channel not supported: '+file) + end + if f.read(1)[0]!=0 + self.Error('Unknown compression method: '+file) + end + if f.read(1)[0]!=0 + self.Error('Unknown filter method: '+file) + end + if f.read(1)[0]!=0 + self.Error('Interlacing not supported: '+file) + end + f.read(4) + parms='/DecodeParms <>' + # 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]] + elsif ct==2 + trns=[t[1],t[3],t[5]] + else + pos=t.index(0) + trns=[pos] unless pos.nil? + 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=='' + self.Error('Missing palette in '+file) + end + f.close + {'w'=>w,'h'=>h,'cs'=>colspace,'bpc'=>bpc,'f'=>'FlateDecode', + 'parms'=>parms,'pal'=>pal,'trns'=>trns,'data'=>data} + end + + def freadint(f) + # Read a 4-byte integer from file + a = f.read(4).unpack('N') + return a[0] + end + + def freadshort(f) + a = f.read(2).unpack('n') + return a[0] + end + + def freadbyte(f) + a = f.read(1).unpack('C') + return a[0] + end + + def textstring(s) + # Format a text string + '('+escape(s)+')' + end + + def escape(s) + # Add \ before \, ( and ) + s.gsub('\\','\\\\\\').gsub('(','\\(').gsub(')','\\)') + end + + def putstream(s) + out('stream') + out(s) + out('endstream') + end + + def out(s) + # Add a line to the document + if @state==2 + @pages[@page]=@pages[@page]+s+"\n" + else + @buffer=@buffer+s.to_s+"\n" + end + end + + # jpeg marker codes + + M_SOF0 = 0xc0 + M_SOF1 = 0xc1 + M_SOF2 = 0xc2 + M_SOF3 = 0xc3 + + M_SOF5 = 0xc5 + M_SOF6 = 0xc6 + M_SOF7 = 0xc7 + + M_SOF9 = 0xc9 + M_SOF10 = 0xca + M_SOF11 = 0xcb + + M_SOF13 = 0xcd + M_SOF14 = 0xce + M_SOF15 = 0xcf + + M_SOI = 0xd8 + M_EOI = 0xd9 + M_SOS = 0xda + + def extractjpginfo(file) + result = nil + + open(file, "rb") do |f| + marker = jpegnextmarker(f) + + if marker != M_SOI + return nil + end + + while true + marker = jpegnextmarker(f) + + case marker + when M_SOF0, M_SOF1, M_SOF2, M_SOF3, + M_SOF5, M_SOF6, M_SOF7, M_SOF9, + M_SOF10, M_SOF11, M_SOF13, M_SOF14, + M_SOF15 then + + length = freadshort(f) + + if result.nil? + result = {} + + result['bits'] = freadbyte(f) + result['height'] = freadshort(f) + result['width'] = freadshort(f) + result['channels'] = freadbyte(f) + + f.seek(length - 8, IO::SEEK_CUR) + else + f.seek(length - 2, IO::SEEK_CUR) + end + when M_SOS, M_EOI then + return result + else + length = freadshort(f) + f.seek(length - 2, IO::SEEK_CUR) + end + end + end + end + + def jpegnextmarker(f) + while true + # look for 0xff + while (c = freadbyte(f)) != 0xff + end + + c = freadbyte(f) + + if c != 0 + return c + end + end + end +end diff --git a/lib/plugins/rfpdf/lib/rfpdf/math.rb b/lib/plugins/rfpdf/lib/rfpdf/math.rb new file mode 100644 index 000000000..f339af267 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/math.rb @@ -0,0 +1,90 @@ +# Various mathematical calculations extracted from the PDF::Writer for Ruby gem. +# - http://rubyforge.org/projects/ruby-pdf +# - Copyright 2003 - 2005 Austin Ziegler. +# - Licensed under a MIT-style licence. +# + +module RFPDF::Math + PI2 = ::Math::PI * 2.0 + + # One degree of arc measured in terms of radians. + DR = PI2 / 360.0 + # One radian of arc, measured in terms of degrees. + RD = 360 / PI2 + # One degree of arc, measured in terms of gradians. + DG = 400 / 360.0 + # One gradian of arc, measured in terms of degrees. + GD = 360 / 400.0 + # One radian of arc, measured in terms of gradians. + RG = 400 / PI2 + # One gradian of arc, measured in terms of radians. + GR = PI2 / 400.0 + + # Truncate the remainder. + def remt(num, den) + num - den * (num / den.to_f).to_i + end + + # Wrap radian values within the range of radians (0..PI2). + def rad2rad(rad) + remt(rad, PI2) + end + + # Wrap degree values within the range of degrees (0..360). + def deg2deg(deg) + remt(deg, 360) + end + + # Wrap gradian values within the range of gradians (0..400). + def grad2grad(grad) + remt(grad, 400) + end + + # Convert degrees to radians. The value will be constrained to the + # range of radians (0..PI2) unless +wrap+ is false. + def deg2rad(deg, wrap = true) + rad = DR * deg + rad = rad2rad(rad) if wrap + rad + end + + # Convert degrees to gradians. The value will be constrained to the + # range of gradians (0..400) unless +wrap+ is false. + def deg2grad(deg, wrap = true) + grad = DG * deg + grad = grad2grad(grad) if wrap + grad + end + + # Convert radians to degrees. The value will be constrained to the + # range of degrees (0..360) unless +wrap+ is false. + def rad2deg(rad, wrap = true) + deg = RD * rad + deg = deg2deg(deg) if wrap + deg + end + + # Convert radians to gradians. The value will be constrained to the + # range of gradians (0..400) unless +wrap+ is false. + def rad2grad(rad, wrap = true) + grad = RG * rad + grad = grad2grad(grad) if wrap + grad + end + + # Convert gradians to degrees. The value will be constrained to the + # range of degrees (0..360) unless +wrap+ is false. + def grad2deg(grad, wrap = true) + deg = GD * grad + deg = deg2deg(deg) if wrap + deg + end + + # Convert gradians to radians. The value will be constrained to the + # range of radians (0..PI2) unless +wrap+ is false. + def grad2rad(grad, wrap = true) + rad = GR * grad + rad = rad2rad(rad) if wrap + rad + end +end diff --git a/lib/plugins/rfpdf/lib/rfpdf/template_handler/compile_support.rb b/lib/plugins/rfpdf/lib/rfpdf/template_handler/compile_support.rb new file mode 100644 index 000000000..b0129f086 --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/template_handler/compile_support.rb @@ -0,0 +1,73 @@ +module RFPDF + module TemplateHandler + + class CompileSupport + # extend ActiveSupport::Memoizable + + attr_reader :options + + def initialize(controller) + @controller = controller + @options = pull_options + set_headers + end + + def pull_options + @controller.send :compute_rfpdf_options || {} + end + + def set_headers + set_pragma + set_cache_control + set_content_type + set_disposition + end + + # TODO: kept around from railspdf-- maybe not needed anymore? should check. + def ie_request? + @controller.request.env['HTTP_USER_AGENT'] =~ /msie/i + end + # memoize :ie_request? + + # added to make ie happy with ssl pdf's (per naisayer) + def ssl_request? + # @controller.request.env['SERVER_PROTOCOL'].downcase == "https" + @controller.request.ssl? + end + # memoize :ssl_request? + + # TODO: kept around from railspdf-- maybe not needed anymore? should check. + def set_pragma + if ssl_request? && ie_request? + @controller.headers['Pragma'] = 'public' # added to make ie ssl pdfs work (per naisayer) + else + @controller.headers['Pragma'] ||= ie_request? ? 'no-cache' : '' + end + end + + # TODO: kept around from railspdf-- maybe not needed anymore? should check. + def set_cache_control + if ssl_request? && ie_request? + @controller.headers['Cache-Control'] = 'maxage=1' # added to make ie ssl pdfs work (per naisayer) + else + @controller.headers['Cache-Control'] ||= ie_request? ? 'no-cache, must-revalidate' : '' + end + end + + def set_content_type + @controller.response.content_type ||= Mime::PDF + end + + def set_disposition + inline = options[:inline] ? 'inline' : 'attachment' + filename = options[:filename] ? "filename=#{options[:filename]}" : nil + @controller.headers["Content-Disposition"] = [inline,filename].compact.join(';') + end + + end + + end +end + + + diff --git a/lib/plugins/rfpdf/lib/rfpdf/template_handlers/base.rb b/lib/plugins/rfpdf/lib/rfpdf/template_handlers/base.rb new file mode 100644 index 000000000..a7b15453e --- /dev/null +++ b/lib/plugins/rfpdf/lib/rfpdf/template_handlers/base.rb @@ -0,0 +1,12 @@ +module RFPDF + module TemplateHandlers + # class Base < ::ActionView::TemplateHandlers::ERB + + # def compile(template) + # src = "_rfpdf_compile_setup;" + super + # end + # end + end +end + + diff --git a/lib/plugins/rfpdf/lib/tcpdf.rb b/lib/plugins/rfpdf/lib/tcpdf.rb new file mode 100644 index 000000000..3bca80972 --- /dev/null +++ b/lib/plugins/rfpdf/lib/tcpdf.rb @@ -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, h3, 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.
    +# This class is an extension and improvement of the FPDF class by Olivier Plathey (http://www.fpdf.org).
    +# 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]
    +# TCPDF project (http://tcpdf.sourceforge.net) is based on the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org).
    +# 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):

  • test break
    second line
    third line
  • font + 3
  • small text
  • normal subscript superscript

  • table:
    #AB
    1A1B1
    2A2 € € € & è è B2
    3A3B3

    image:
    \"test"; + + + # ENGLISH + + @l = {} + + # PAGE META DESCRIPTORS -------------------------------------- + + @l['a_meta_charset'] = "UTF-8"; + @l['a_meta_dir'] = "ltr"; + @l['a_meta_language'] = "en"; + + # TRANSLATIONS -------------------------------------- + @l['w_page'] = "page"; + + + # create new PDF document (document units are set by default to millimeters) + pdf = TCPDF.new + + # set document information + pdf.SetCreator("TCPDF"); + pdf.SetAuthor("TCPDF"); + pdf.SetTitle(doc_title); + pdf.SetSubject(doc_subject); + pdf.SetKeywords(doc_keywords); + + pdf.SetHeaderData("#{File.join(RAILS_ROOT, 'public')}/logo_example.png", 20, "header title", "first row\nsecond row\nthird row"); + + #set margins + pdf.SetMargins(15, 27, 15); + #set auto page breaks + pdf.SetAutoPageBreak(true, 25); + pdf.SetPrintHeader + pdf.SetPrintFooter + pdf.SetHeaderMargin(5); + pdf.SetFooterMargin(10); + pdf.SetImageScale(4); #set image scale factor + + pdf.SetHeaderFont(["FreeSans", '', 10]); + pdf.SetFooterFont(["FreeSans", '', 8]); + + pdf.SetLanguageArray(@l); #set language items + + + #initialize document + pdf.alias_nb_pages(); + + pdf.AddPage(); + + # set barcode + # pdf.SetBarcode(Time.now.strftime("Y-m-d H:i:s")); + + # output some HTML code + pdf.SetFont("vera", "", 10); + + pdf.writeHTML(htmlcontent, true, 0); + + # output two html columns + first_column_width = 80; + current_y_position = pdf.GetY(); + pdf.writeHTMLCell(first_column_width, 0, 0, current_y_position, "hello", 0, 0, 0); + pdf.writeHTMLCell(0, 0, first_column_width, current_y_position, "world", 0, 1, 0); + + # output some content + pdf.SetFont("vera", "BI", 20); + pdf.Cell(0,10,"TEST Bold-Italic Cell",1,1,'C'); + + # output some UTF-8 test content + pdf.AddPage(); + pdf.SetFont("FreeSans", "", 12); + utf8text = open(File.join(RAILS_ROOT, 'vendor/plugins/rfpdf',"utf8test.txt"), "rb").read; # get utf-8 text form file + pdf.SetFillColor(230, 240, 255, true); + pdf.Write(5, utf8text, '', 1); + + # remove page header/footer + pdf.SetPrintHeader(false); + pdf.SetPrintFooter(false); + + # Two HTML columns test + pdf.AddPage(); + right_column = "right column right column right column right column right column + right column right column right column right column right column right column + right column right column right column right column right column right column"; + left_column = "left column left column left column left column left column left + column left column left column left column left column left column left column + left column left column left column left column left column left column left + column"; + first_column_width = 80; + second_column_width = 80; + column_space = 20; + current_y_position = pdf.GetY(); + pdf.writeHTMLCell(first_column_width, 0, 0, 0, left_column, 1, 0, 0); + pdf.Cell(0); + pdf.writeHTMLCell(second_column_width, 0, first_column_width+column_space, current_y_position, right_column, 0, 0, 0); + + # add page header/footer + pdf.SetPrintHeader(true); + pdf.SetPrintFooter(true); + + pdf.AddPage(); + + # Multicell test + pdf.MultiCell(40, 5, "A test multicell line 1\ntest multicell line 2\ntest multicell line 3", 1, 'J', 0, 0); + pdf.MultiCell(40, 5, "B test multicell line 1\ntest multicell line 2\ntest multicell line 3", 1, 'J', 0); + pdf.MultiCell(40, 5, "C test multicell line 1\ntest multicell line 2\ntest multicell line 3", 1, 'J', 0, 0); + pdf.MultiCell(40, 5, "D test multicell line 1\ntest multicell line 2\ntest multicell line 3", 1, 'J', 0, 2); + pdf.MultiCell(40, 5, "F test multicell line 1\ntest multicell line 2\ntest multicell line 3", 1, 'J', 0); + + #Close and output PDF document +%><%=pdf.Output()%> \ No newline at end of file diff --git a/lib/plugins/rfpdf/utf8test.txt b/lib/plugins/rfpdf/utf8test.txt new file mode 100644 index 000000000..fa0f4b75e --- /dev/null +++ b/lib/plugins/rfpdf/utf8test.txt @@ -0,0 +1,135 @@ +Sentences that contain all letters commonly used in a language +-------------------------------------------------------------- + +Markus Kuhn -- 2001-09-02 + +This file is UTF-8 encoded. + + +Danish (da) +--------- + + Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen + Wolther spillede pÃ¥ xylofon. + (= Quiz contestants were eating strawbery with cream while Wolther + the circus clown played on xylophone.) + +German (de) +----------- + + Falsches Üben von Xylophonmusik quält jeden größeren Zwerg + (= Wrongful practicing of xylophone music tortures every larger dwarf) + + Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich + (= Twelve boxing fighters hunted Eva across the dike of Sylt) + + Heizölrückstoßabdämpfung + (= fuel oil recoil absorber) + (jqvwxy missing, but all non-ASCII letters in one word) + +English (en) +------------ + + The quick brown fox jumps over the lazy dog + +Spanish (es) +------------ + + El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y + frío, añoraba a su querido cachorro. + (Contains every letter and every accent, but not every combination + of vowel + acute.) + +French (fr) +----------- + + Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à + côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce + qui lui permet de penser à la cænogenèse de l'être dont il est question + dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, + pense-t-il, diminue çà et là la qualité de son Å“uvre. + + l'île exiguë + Où l'obèse jury mûr + Fête l'haï volapük, + Âne ex aéquo au whist, + Ôtez ce vÅ“u déçu. + + Le cÅ“ur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en + canoë au delà des îles, près du mälström où brûlent les novæ. + +Irish Gaelic (ga) +----------------- + + D'fhuascail Ãosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ãdhaimh + +Hungarian (hu) +-------------- + + ÃrvíztűrÅ‘ tükörfúrógép + (= flood-proof mirror-drilling machine, only all non-ASCII letters) + +Icelandic (is) +-------------- + + Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa + + Sævör grét áðan því úlpan var ónýt + (some ASCII letters missing) + +Greek (el) +------------- + + Γαζέες καὶ μυÏτιὲς δὲν θὰ βÏá¿¶ πιὰ στὸ χÏυσαφὶ ξέφωτο + (= No more shall I see acacias or myrtles in the golden clearing) + + Ξεσκεπάζω τὴν ψυχοφθόÏα βδελυγμία + (= I uncover the soul-destroying abhorrence) + +Japanese (jp) +------------- + + Hiragana: (Iroha) + + ã„ã‚ã¯ã«ã»ã¸ã¨ã¡ã‚Šã¬ã‚‹ã‚’ + ã‚ã‹ã‚ˆãŸã‚Œãã¤ã­ãªã‚‰ã‚€ + ã†ã‚ã®ãŠãã‚„ã¾ã‘ãµã“ãˆã¦ + ã‚ã•ãゆã‚ã¿ã—ã‚‘ã²ã‚‚ã›ã™ + + Katakana: + + イロãƒãƒ‹ãƒ›ãƒ˜ãƒˆ ãƒãƒªãƒŒãƒ«ãƒ² ワカヨタレソ ツãƒãƒŠãƒ©ãƒ  + ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン + +Hebrew (iw) +----------- + + ? דג סקרן שט ×‘×™× ×ž×וכזב ולפתע ×ž×¦× ×œ×• חברה ×יך הקליטה + +Polish (pl) +----------- + + Pchnąć w tÄ™ łódź jeża lub oÅ›m skrzyÅ„ fig + (= To push a hedgehog or eight bins of figs in this boat) + +Russian (ru) +------------ + + Ð’ чащах юга жил бы цитруÑ? Да, но фальшивый ÑкземплÑÑ€! + (= Would a citrus live in the bushes of south? Yes, but only a fake one!) + +Thai (th) +--------- + + [--------------------------|------------------------] + ๠เป็นมนุษย์สุดประเสริà¸à¹€à¸¥à¸´à¸¨à¸„ุณค่า à¸à¸§à¹ˆà¸²à¸šà¸£à¸£à¸”าà¸à¸¹à¸‡à¸ªà¸±à¸•ว์เดรัจฉาน + จงà¸à¹ˆà¸²à¸Ÿà¸±à¸™à¸žà¸±à¸’นาวิชาà¸à¸²à¸£ อย่าล้างผลาà¸à¸¤à¹…เข่นฆ่าบีฑาใคร + ไม่ถือโทษโà¸à¸£à¸˜à¹à¸Šà¹ˆà¸‡à¸‹à¸±à¸”ฮึดฮัดด่า หัดอภัยเหมือนà¸à¸µà¸¬à¸²à¸­à¸±à¸Šà¸Œà¸²à¸ªà¸±à¸¢ + ปà¸à¸´à¸šà¸±à¸•ิประพฤติà¸à¸Žà¸à¸³à¸«à¸™à¸”ใจ พูดจาให้จ๊ะๆ จ๋าๆ น่าฟังเอย ฯ + + [The copyright for the Thai example is owned by The Computer + Association of Thailand under the Royal Patronage of His Majesty the + King.] + +Please let me know if you find others! Special thanks to the people +from all over the world who contributed these sentences. diff --git a/lib/redcloth3.rb b/lib/redcloth3.rb new file mode 100644 index 000000000..b0bda81a5 --- /dev/null +++ b/lib/redcloth3.rb @@ -0,0 +1,1208 @@ +# 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 +# +# h3. 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: +# +# This is a link +# +# == 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: +# +# Textist +# +# With a link: +# +# !/common/textist.gif(Textist)!:http://textism.com +# +# Will become: +# +# Textist +# +# == 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: +# +# ACLU +# +# == 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 " +# +# h3. 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 fell!" + # + 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., h3., 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 bold man", [:filter_html] ) + # r.to_html + # #=>"

    A <b>bold</b> man

    " + # + 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 fell!" + # + 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%/, '&' ) + 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’\2' ], # single closing + # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing + # [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing + # [ /\'/, '‘' ], # single opening + # [ //, '>' ], # greater-than + # [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing + # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing + # [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing + # [ /"/, '“' ], # double opening + # [ /\b( )?\.{3}/, '\1…' ], # ellipsis + # [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '\1' ], # 3+ uppercase acronym + # [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^\2\3', :no_span_caps ], # 3+ uppercase caps + # [ /(\.\s)?\s?--\s?/, '\1—' ], # em dash + # [ /\s->\s/, ' → ' ], # right arrow + # [ /\s-\s/, ' – ' ], # en dash + # [ /(\d+) ?x ?(\d+)/, '\1×\2' ], # dimension sign + # [ /\b ?[(\[]TM[\])]/i, '™' ], # trademark + # [ /\b ?[(\[]R[\])]/i, '®' ], # registered + # [ /\b ?[(\[]C[\])]/i, '©' ] # 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!( '&', '&' ) + str.gsub!( '"', '"' ) if mode != :NoQuotes + str.gsub!( "'", ''' ) if mode == :Quotes + str.gsub!( '<', '<') + str.gsub!( '>', '>') + 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| + "#{$1}" + 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 + + if text.sub!( /\{([^"}]*)\}/, '' ) && !filter_styles + sanitized = sanitize_styles($1) + style << "#{ sanitized };" unless sanitized.blank? + end + + 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 + + STYLES_RE = /^(color|width|height|border|background|padding|margin|font|text|float)(-[a-z]+)*:\s*((\d+%?|\d+px|\d+(\.\d+)?em|#[0-9a-f]+|[a-z]+)\s*)+$/i + + def sanitize_styles(str) + styles = str.split(";").map(&:strip) + styles.reject! do |style| + !style.match(STYLES_RE) + end + styles.join(";") + 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#{ cell }" + end + ratts = shelve( ratts ) if ratts + rows << "\t\t\n#{ cells.join( "\n" ) }\n\t\t" + end + "\t\n#{ rows.join( "\n" ) }\n\t\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] << "\n\t\n\t" + depth.pop + end + end + if depth.last and depth.last.length == tl.length + lines[line_id - 1] << '' + 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
  • #{ content }" + else + lines[line_id] = "\t\t
  • #{ content }" + end + last_line = line_id + + else + last_line = line_id + end + if line_id - last_line > 1 or line_id == lines.length - 1 + while v = depth.pop + lines[last_line] << "
  • \n\t" + 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 ? '
    ' * (l-indent) : '
    ' * (indent-l)) + "\n\n") + indent = l + end + quotes << (content + "\n") + end + quotes << ("\n" + '' * 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 }

    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 literal 0 HcmV?d00001 diff --git a/files/2013/07/130729153346_737521_50.jpg b/files/2013/07/130729153346_737521_50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..68a02e4a767b75ac8e60fe0aaae58bc5a73368bf GIT binary patch literal 1264 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!$*1bTN93k?^)I7a%<;;+0#nS^4xpy?v~xm zb+hgt>5uwf zt0g_BmTfam{ZZ0(Q+9dc?rj%i{;hn_Y4ST$t?z-y3U1Mqg9rX(Z{PE=_U+ZjnNoIh zpP!dwoaERVU-NTS@!#Ry0{CPdZiDCdnje*uP%+ z*Y&`Mvt^wwAGvlsu=c%twFKUp)Vfw?rmWp7d>IxvhH_|Co2B zVk6&DgT{-Jo^|YThB22+CT;7O9vLf$;U0M}ziAz1d~6 zc6GGTvcsFw6l5k|SjYJFIrE=t$*(I_H<(KmRepOtXVb?Y>nfCX`uZPn54@l@OI=O* z&}P2nw>s7xEn3c(R*+iYao$T)W8GruMbBJKH#myU`_+?q;Iw?!(!!O#N^kuqlpl}M zQx(f}l)B4WHYv4&@6d;BGJFlcf7OL9Wb0mL`f}2LhN#|~7gqevtT^?2;d#rW#bwj` z(+gB&nh$Hf;}49Ey85U5T2*0>_EddI9_tMfrhVH@_V(?%?XV};NY_qY#NTvs@4gVh znl;N;@cA>Z{}Gxmd^VqVjhWcOFo}lH(0?!9|M<_~b@A#RXCAH%(Ni + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/lib/SVG/Graph/Bar.rb b/lib/SVG/Graph/Bar.rb new file mode 100644 index 000000000..695156594 --- /dev/null +++ b/lib/SVG/Graph/Bar.rb @@ -0,0 +1,148 @@ +require 'rexml/document' +require 'SVG/Graph/Graph' +require 'SVG/Graph/BarBase' + +module SVG + module Graph + # === Create presentation quality SVG bar graphs easily + # + # = Synopsis + # + # require 'SVG/Graph/Bar' + # + # fields = %w(Jan Feb Mar); + # data_sales_02 = [12, 45, 21] + # + # graph = SVG::Graph::Bar.new( + # :height => 500, + # :width => 300, + # :fields => fields + # ) + # + # graph.add_data( + # :data => data_sales_02, + # :title => 'Sales 2002' + # ) + # + # print "Content-type: image/svg+xml\r\n\r\n" + # print graph.burn + # + # = Description + # + # This object aims to allow you to easily create high quality + # SVG[http://www.w3c.org/tr/svg bar graphs. You can either use the default + # style sheet or supply your own. Either way there are many options which + # can be configured to give you control over how the graph is generated - + # with or without a key, data elements at each point, title, subtitle etc. + # + # = Notes + # + # The default stylesheet handles upto 12 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 12 data sets as they will have no style and + # be in black. + # + # = Examples + # + # * http://germane-software.com/repositories/public/SVG/test/test.rb + # + # = See also + # + # * SVG::Graph::Graph + # * SVG::Graph::BarHorizontal + # * SVG::Graph::Line + # * SVG::Graph::Pie + # * SVG::Graph::Plot + # * SVG::Graph::TimeSeries + class Bar < BarBase + include REXML + + # See Graph::initialize and BarBase::set_defaults + def set_defaults + super + self.top_align = self.top_font = 1 + end + + protected + + def get_x_labels + @config[:fields] + end + + def get_y_labels + maxvalue = max_value + minvalue = min_value + range = maxvalue - minvalue + + top_pad = range == 0 ? 10 : range / 20.0 + scale_range = (maxvalue + top_pad) - minvalue + + scale_division = scale_divisions || (scale_range / 10.0) + + if scale_integers + scale_division = scale_division < 1 ? 1 : scale_division.round + end + + rv = [] + maxvalue = maxvalue%scale_division == 0 ? + maxvalue : maxvalue + scale_division + minvalue.step( maxvalue, scale_division ) {|v| rv << v} + return rv + end + + def x_label_offset( width ) + width / 2.0 + end + + def draw_data + minvalue = min_value + fieldwidth = field_width + + unit_size = (@graph_height.to_f - font_size*2*top_font) / + (get_y_labels.max - get_y_labels.min) + bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0 + + bar_width = fieldwidth - bargap + bar_width /= @data.length if stack == :side + x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0) + + bottom = @graph_height + + field_count = 0 + @config[:fields].each_index { |i| + dataset_count = 0 + for dataset in @data + + # cases (assume 0 = +ve): + # value min length + # +ve +ve value - min + # +ve -ve value - 0 + # -ve -ve value.abs - 0 + + value = dataset[:data][i] + + left = (fieldwidth * field_count) + + length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size + # top is 0 if value is negative + top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size) + left += bar_width * dataset_count if stack == :side + + @graph.add_element( "rect", { + "x" => left.to_s, + "y" => top.to_s, + "width" => bar_width.to_s, + "height" => length.to_s, + "class" => "fill#{dataset_count+1}" + }) + + make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s) + dataset_count += 1 + end + field_count += 1 + } + end + end + end +end diff --git a/lib/SVG/Graph/BarBase.rb b/lib/SVG/Graph/BarBase.rb new file mode 100644 index 000000000..7b7dda887 --- /dev/null +++ b/lib/SVG/Graph/BarBase.rb @@ -0,0 +1,139 @@ +require 'rexml/document' +require 'SVG/Graph/Graph' + +module SVG + module Graph + # = Synopsis + # + # A superclass for bar-style graphs. Do not attempt to instantiate + # directly; use one of the subclasses instead. + # + # = Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class BarBase < SVG::Graph::Graph + # Ensures that :fields are provided in the configuration. + def initialize config + raise "fields was not supplied or is empty" unless config[:fields] && + config[:fields].kind_of?(Array) && + config[:fields].length > 0 + super + end + + # In addition to the defaults set in Graph::initialize, sets + # [bar_gap] true + # [stack] :overlap + def set_defaults + init_with( :bar_gap => true, :stack => :overlap ) + end + + # Whether to have a gap between the bars or not, default + # is true, set to false if you don't want gaps. + attr_accessor :bar_gap + # How to stack data sets. :overlap overlaps bars with + # transparent colors, :top stacks bars on top of one another, + # :side stacks the bars side-by-side. Defaults to :overlap. + attr_accessor :stack + + + protected + + def max_value + @data.collect{|x| x[:data].max}.max + end + + def min_value + min = 0 + if min_scale_value.nil? + min = @data.collect{|x| x[:data].min}.min + min = min > 0 ? 0 : min + else + min = min_scale_value + end + return min + end + + def get_css + return < 500, + # :width => 300, + # :fields => fields, + # }) + # + # graph.add_data({ + # :data => data_sales_02, + # :title => 'Sales 2002', + # }) + # + # print "Content-type: image/svg+xml\r\n\r\n" + # print graph.burn + # + # = Description + # + # This object aims to allow you to easily create high quality + # SVG horitonzal bar graphs. You can either use the default style sheet + # or supply your own. Either way there are many options which can + # be configured to give you control over how the graph is + # generated - with or without a key, data elements at each point, + # title, subtitle etc. + # + # = Examples + # + # * http://germane-software.com/repositories/public/SVG/test/test.rb + # + # = See also + # + # * SVG::Graph::Graph + # * SVG::Graph::Bar + # * SVG::Graph::Line + # * SVG::Graph::Pie + # * SVG::Graph::Plot + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class BarHorizontal < BarBase + # In addition to the defaults set in BarBase::set_defaults, sets + # [rotate_y_labels] true + # [show_x_guidelines] true + # [show_y_guidelines] false + def set_defaults + super + init_with( + :rotate_y_labels => true, + :show_x_guidelines => true, + :show_y_guidelines => false + ) + self.right_align = self.right_font = 1 + end + + protected + + def get_x_labels + maxvalue = max_value + minvalue = min_value + range = maxvalue - minvalue + top_pad = range == 0 ? 10 : range / 20.0 + scale_range = (maxvalue + top_pad) - minvalue + + scale_division = scale_divisions || (scale_range / 10.0) + + if scale_integers + scale_division = scale_division < 1 ? 1 : scale_division.round + end + + rv = [] + maxvalue = maxvalue%scale_division == 0 ? + maxvalue : maxvalue + scale_division + minvalue.step( maxvalue, scale_division ) {|v| rv << v} + return rv + end + + def get_y_labels + @config[:fields] + end + + def y_label_offset( height ) + height / -2.0 + end + + def draw_data + minvalue = min_value + fieldheight = field_height + + unit_size = (@graph_width.to_f - font_size*2*right_font ) / + (get_x_labels.max - get_x_labels.min ) + bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0 + + bar_height = fieldheight - bargap + bar_height /= @data.length if stack == :side + y_mod = (bar_height / 2) + (font_size / 2) + + field_count = 1 + @config[:fields].each_index { |i| + dataset_count = 0 + for dataset in @data + value = dataset[:data][i] + + top = @graph_height - (fieldheight * field_count) + top += (bar_height * dataset_count) if stack == :side + # cases (assume 0 = +ve): + # value min length left + # +ve +ve value.abs - min minvalue.abs + # +ve -ve value.abs - 0 minvalue.abs + # -ve -ve value.abs - 0 minvalue.abs + value + length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size + left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size + + @graph.add_element( "rect", { + "x" => left.to_s, + "y" => top.to_s, + "width" => length.to_s, + "height" => bar_height.to_s, + "class" => "fill#{dataset_count+1}" + }) + + make_datapoint_text( + left+length+5, top+y_mod, value, "text-anchor: start; " + ) + dataset_count += 1 + end + field_count += 1 + } + end + end + end +end diff --git a/lib/SVG/Graph/Graph.rb b/lib/SVG/Graph/Graph.rb new file mode 100644 index 000000000..8a840b2f1 --- /dev/null +++ b/lib/SVG/Graph/Graph.rb @@ -0,0 +1,978 @@ +begin + require 'zlib' + @@__have_zlib = true +rescue + @@__have_zlib = false +end + +require 'rexml/document' + +module SVG + module Graph + VERSION = '@ANT_VERSION@' + + # === Base object for generating SVG Graphs + # + # == Synopsis + # + # This class is only used as a superclass of specialized charts. Do not + # attempt to use this class directly, unless creating a new chart type. + # + # For examples of how to subclass this class, see the existing specific + # subclasses, such as SVG::Graph::Pie. + # + # == Examples + # + # For examples of how to use this package, see either the test files, or + # the documentation for the specific class you want to use. + # + # * file:test/plot.rb + # * file:test/single.rb + # * file:test/test.rb + # * file:test/timeseries.rb + # + # == Description + # + # This package should be used as a base for creating SVG graphs. + # + # == Acknowledgements + # + # Leo Lapworth for creating the SVG::TT::Graph package which this Ruby + # port is based on. + # + # Stephen Morgan for creating the TT template and SVG. + # + # == See + # + # * SVG::Graph::BarHorizontal + # * SVG::Graph::Bar + # * SVG::Graph::Line + # * SVG::Graph::Pie + # * SVG::Graph::Plot + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class Graph + include REXML + + # Initialize the graph object with the graph settings. You won't + # instantiate this class directly; see the subclass for options. + # [width] 500 + # [height] 300 + # [show_x_guidelines] false + # [show_y_guidelines] true + # [show_data_values] true + # [min_scale_value] 0 + # [show_x_labels] true + # [stagger_x_labels] false + # [rotate_x_labels] false + # [step_x_labels] 1 + # [step_include_first_x_label] true + # [show_y_labels] true + # [rotate_y_labels] false + # [scale_integers] false + # [show_x_title] false + # [x_title] 'X Field names' + # [show_y_title] false + # [y_title_text_direction] :bt + # [y_title] 'Y Scale' + # [show_graph_title] false + # [graph_title] 'Graph Title' + # [show_graph_subtitle] false + # [graph_subtitle] 'Graph Sub Title' + # [key] true, + # [key_position] :right, # bottom or righ + # [font_size] 12 + # [title_font_size] 16 + # [subtitle_font_size] 14 + # [x_label_font_size] 12 + # [x_title_font_size] 14 + # [y_label_font_size] 12 + # [y_title_font_size] 14 + # [key_font_size] 10 + # [no_css] false + # [add_popups] false + def initialize( config ) + @config = config + + self.top_align = self.top_font = self.right_align = self.right_font = 0 + + init_with({ + :width => 500, + :height => 300, + :show_x_guidelines => false, + :show_y_guidelines => true, + :show_data_values => true, + +# :min_scale_value => 0, + + :show_x_labels => true, + :stagger_x_labels => false, + :rotate_x_labels => false, + :step_x_labels => 1, + :step_include_first_x_label => true, + + :show_y_labels => true, + :rotate_y_labels => false, + :stagger_y_labels => false, + :scale_integers => false, + + :show_x_title => false, + :x_title => 'X Field names', + + :show_y_title => false, + :y_title_text_direction => :bt, + :y_title => 'Y Scale', + + :show_graph_title => false, + :graph_title => 'Graph Title', + :show_graph_subtitle => false, + :graph_subtitle => 'Graph Sub Title', + :key => true, + :key_position => :right, # bottom or right + + :font_size =>12, + :title_font_size =>16, + :subtitle_font_size =>14, + :x_label_font_size =>12, + :x_title_font_size =>14, + :y_label_font_size =>12, + :y_title_font_size =>14, + :key_font_size =>10, + + :no_css =>false, + :add_popups =>false, + }) + + set_defaults if respond_to? :set_defaults + + init_with config + end + + + # This method allows you do add data to the graph object. + # It can be called several times to add more data sets in. + # + # data_sales_02 = [12, 45, 21]; + # + # graph.add_data({ + # :data => data_sales_02, + # :title => 'Sales 2002' + # }) + def add_data conf + @data = [] unless defined? @data + + if conf[:data] and conf[:data].kind_of? Array + @data << conf + else + raise "No data provided by #{conf.inspect}" + end + end + + + # This method removes all data from the object so that you can + # reuse it to create a new graph but with the same config options. + # + # graph.clear_data + def clear_data + @data = [] + end + + + # This method processes the template with the data and + # config which has been set and returns the resulting SVG. + # + # This method will croak unless at least one data set has + # been added to the graph object. + # + # print graph.burn + def burn + raise "No data available" unless @data.size > 0 + + calculations if respond_to? :calculations + + start_svg + calculate_graph_dimensions + @foreground = Element.new( "g" ) + draw_graph + draw_titles + draw_legend + draw_data + @graph.add_element( @foreground ) + style + + data = "" + @doc.write( data, 0 ) + + if @config[:compress] + if @@__have_zlib + inp, out = IO.pipe + gz = Zlib::GzipWriter.new( out ) + gz.write data + gz.close + data = inp.read + else + data << ""; + end + end + + return data + end + + + # Set the height of the graph box, this is the total height + # of the SVG box created - not the graph it self which auto + # scales to fix the space. + attr_accessor :height + # Set the width of the graph box, this is the total width + # of the SVG box created - not the graph it self which auto + # scales to fix the space. + attr_accessor :width + # Set the path to an external stylesheet, set to '' if + # you want to revert back to using the defaut internal version. + # + # To create an external stylesheet create a graph using the + # default internal version and copy the stylesheet section to + # an external file and edit from there. + attr_accessor :style_sheet + # (Bool) Show the value of each element of data on the graph + attr_accessor :show_data_values + # The point at which the Y axis starts, defaults to '0', + # if set to nil it will default to the minimum data value. + attr_accessor :min_scale_value + # Whether to show labels on the X axis or not, defaults + # to true, set to false if you want to turn them off. + attr_accessor :show_x_labels + # This puts the X labels at alternative levels so if they + # are long field names they will not overlap so easily. + # Default it false, to turn on set to true. + attr_accessor :stagger_x_labels + # This puts the Y labels at alternative levels so if they + # are long field names they will not overlap so easily. + # Default it false, to turn on set to true. + attr_accessor :stagger_y_labels + # This turns the X axis labels by 90 degrees. + # Default it false, to turn on set to true. + attr_accessor :rotate_x_labels + # This turns the Y axis labels by 90 degrees. + # Default it false, to turn on set to true. + attr_accessor :rotate_y_labels + # How many "steps" to use between displayed X axis labels, + # a step of one means display every label, a step of two results + # in every other label being displayed (label label label), + # a step of three results in every third label being displayed + # (label label label) and so on. + attr_accessor :step_x_labels + # Whether to (when taking "steps" between X axis labels) step from + # the first label (i.e. always include the first label) or step from + # the X axis origin (i.e. start with a gap if step_x_labels is greater + # than one). + attr_accessor :step_include_first_x_label + # Whether to show labels on the Y axis or not, defaults + # to true, set to false if you want to turn them off. + attr_accessor :show_y_labels + # Ensures only whole numbers are used as the scale divisions. + # Default it false, to turn on set to true. This has no effect if + # scale divisions are less than 1. + attr_accessor :scale_integers + # This defines the gap between markers on the Y axis, + # default is a 10th of the max_value, e.g. you will have + # 10 markers on the Y axis. NOTE: do not set this too + # low - you are limited to 999 markers, after that the + # graph won't generate. + attr_accessor :scale_divisions + # Whether to show the title under the X axis labels, + # default is false, set to true to show. + attr_accessor :show_x_title + # What the title under X axis should be, e.g. 'Months'. + attr_accessor :x_title + # Whether to show the title under the Y axis labels, + # default is false, set to true to show. + attr_accessor :show_y_title + # Aligns writing mode for Y axis label. + # Defaults to :bt (Bottom to Top). + # Change to :tb (Top to Bottom) to reverse. + attr_accessor :y_title_text_direction + # What the title under Y axis should be, e.g. 'Sales in thousands'. + attr_accessor :y_title + # Whether to show a title on the graph, defaults + # to false, set to true to show. + attr_accessor :show_graph_title + # What the title on the graph should be. + attr_accessor :graph_title + # Whether to show a subtitle on the graph, defaults + # to false, set to true to show. + attr_accessor :show_graph_subtitle + # What the subtitle on the graph should be. + attr_accessor :graph_subtitle + # Whether to show a key, defaults to false, set to + # true if you want to show it. + attr_accessor :key + # Where the key should be positioned, defaults to + # :right, set to :bottom if you want to move it. + attr_accessor :key_position + # Set the font size (in points) of the data point labels + attr_accessor :font_size + # Set the font size of the X axis labels + attr_accessor :x_label_font_size + # Set the font size of the X axis title + attr_accessor :x_title_font_size + # Set the font size of the Y axis labels + attr_accessor :y_label_font_size + # Set the font size of the Y axis title + attr_accessor :y_title_font_size + # Set the title font size + attr_accessor :title_font_size + # Set the subtitle font size + attr_accessor :subtitle_font_size + # Set the key font size + attr_accessor :key_font_size + # Show guidelines for the X axis + attr_accessor :show_x_guidelines + # Show guidelines for the Y axis + attr_accessor :show_y_guidelines + # Do not use CSS if set to true. Many SVG viewers do not support CSS, but + # not using CSS can result in larger SVGs as well as making it impossible to + # change colors after the chart is generated. Defaults to false. + attr_accessor :no_css + # Add popups for the data points on some graphs + attr_accessor :add_popups + + + protected + + def sort( *arrys ) + sort_multiple( arrys ) + end + + # Overwrite configuration options with supplied options. Used + # by subclasses. + def init_with config + config.each { |key, value| + self.send((key.to_s+"=").to_sym, value ) if respond_to? key.to_sym + } + end + + attr_accessor :top_align, :top_font, :right_align, :right_font + + KEY_BOX_SIZE = 12 + + # Override this (and call super) to change the margin to the left + # of the plot area. Results in @border_left being set. + def calculate_left_margin + @border_left = 7 + # Check for Y labels + max_y_label_height_px = rotate_y_labels ? + y_label_font_size : + get_y_labels.max{|a,b| + a.to_s.length<=>b.to_s.length + }.to_s.length * y_label_font_size * 0.6 + @border_left += max_y_label_height_px if show_y_labels + @border_left += max_y_label_height_px + 10 if stagger_y_labels + @border_left += y_title_font_size + 5 if show_y_title + end + + + # Calculates the width of the widest Y label. This will be the + # character height if the Y labels are rotated + def max_y_label_width_px + return font_size if rotate_y_labels + end + + + # Override this (and call super) to change the margin to the right + # of the plot area. Results in @border_right being set. + def calculate_right_margin + @border_right = 7 + if key and key_position == :right + val = keys.max { |a,b| a.length <=> b.length } + @border_right += val.length * key_font_size * 0.6 + @border_right += KEY_BOX_SIZE + @border_right += 10 # Some padding around the box + end + end + + + # Override this (and call super) to change the margin to the top + # of the plot area. Results in @border_top being set. + def calculate_top_margin + @border_top = 5 + @border_top += title_font_size if show_graph_title + @border_top += 5 + @border_top += subtitle_font_size if show_graph_subtitle + end + + + # Adds pop-up point information to a graph. + def add_popup( x, y, label ) + txt_width = label.length * font_size * 0.6 + 10 + tx = (x+txt_width > width ? x-5 : x+5) + t = @foreground.add_element( "text", { + "x" => tx.to_s, + "y" => (y - font_size).to_s, + "visibility" => "hidden", + }) + t.attributes["style"] = "fill: #000; "+ + (x+txt_width > width ? "text-anchor: end;" : "text-anchor: start;") + t.text = label.to_s + t.attributes["id"] = t.object_id.to_s + + @foreground.add_element( "circle", { + "cx" => x.to_s, + "cy" => y.to_s, + "r" => "10", + "style" => "opacity: 0", + "onmouseover" => + "document.getElementById(#{t.object_id}).setAttribute('visibility', 'visible' )", + "onmouseout" => + "document.getElementById(#{t.object_id}).setAttribute('visibility', 'hidden' )", + }) + + end + + + # Override this (and call super) to change the margin to the bottom + # of the plot area. Results in @border_bottom being set. + def calculate_bottom_margin + @border_bottom = 7 + if key and key_position == :bottom + @border_bottom += @data.size * (font_size + 5) + @border_bottom += 10 + end + if show_x_labels + max_x_label_height_px = (not rotate_x_labels) ? + x_label_font_size : + get_x_labels.max{|a,b| + a.to_s.length<=>b.to_s.length + }.to_s.length * x_label_font_size * 0.6 + @border_bottom += max_x_label_height_px + @border_bottom += max_x_label_height_px + 10 if stagger_x_labels + end + @border_bottom += x_title_font_size + 5 if show_x_title + end + + + # Draws the background, axis, and labels. + def draw_graph + @graph = @root.add_element( "g", { + "transform" => "translate( #@border_left #@border_top )" + }) + + # Background + @graph.add_element( "rect", { + "x" => "0", + "y" => "0", + "width" => @graph_width.to_s, + "height" => @graph_height.to_s, + "class" => "graphBackground" + }) + + # Axis + @graph.add_element( "path", { + "d" => "M 0 0 v#@graph_height", + "class" => "axis", + "id" => "xAxis" + }) + @graph.add_element( "path", { + "d" => "M 0 #@graph_height h#@graph_width", + "class" => "axis", + "id" => "yAxis" + }) + + draw_x_labels + draw_y_labels + end + + + # Where in the X area the label is drawn + # Centered in the field, should be width/2. Start, 0. + def x_label_offset( width ) + 0 + end + + def make_datapoint_text( x, y, value, style="" ) + if show_data_values + @foreground.add_element( "text", { + "x" => x.to_s, + "y" => y.to_s, + "class" => "dataPointLabel", + "style" => "#{style} stroke: #fff; stroke-width: 2;" + }).text = value.to_s + text = @foreground.add_element( "text", { + "x" => x.to_s, + "y" => y.to_s, + "class" => "dataPointLabel" + }) + text.text = value.to_s + text.attributes["style"] = style if style.length > 0 + end + end + + + # Draws the X axis labels + def draw_x_labels + stagger = x_label_font_size + 5 + if show_x_labels + label_width = field_width + + count = 0 + for label in get_x_labels + if step_include_first_x_label == true then + step = count % step_x_labels + else + step = (count + 1) % step_x_labels + end + + if step == 0 then + text = @graph.add_element( "text" ) + text.attributes["class"] = "xAxisLabels" + text.text = label.to_s + + x = count * label_width + x_label_offset( label_width ) + y = @graph_height + x_label_font_size + 3 + t = 0 - (font_size / 2) + + if stagger_x_labels and count % 2 == 1 + y += stagger + @graph.add_element( "path", { + "d" => "M#{x} #@graph_height v#{stagger}", + "class" => "staggerGuideLine" + }) + end + + text.attributes["x"] = x.to_s + text.attributes["y"] = y.to_s + if rotate_x_labels + text.attributes["transform"] = + "rotate( 90 #{x} #{y-x_label_font_size} )"+ + " translate( 0 -#{x_label_font_size/4} )" + text.attributes["style"] = "text-anchor: start" + else + text.attributes["style"] = "text-anchor: middle" + end + end + + draw_x_guidelines( label_width, count ) if show_x_guidelines + count += 1 + end + end + end + + + # Where in the Y area the label is drawn + # Centered in the field, should be width/2. Start, 0. + def y_label_offset( height ) + 0 + end + + + def field_width + (@graph_width.to_f - font_size*2*right_font) / + (get_x_labels.length - right_align) + end + + + def field_height + (@graph_height.to_f - font_size*2*top_font) / + (get_y_labels.length - top_align) + end + + + # Draws the Y axis labels + def draw_y_labels + stagger = y_label_font_size + 5 + if show_y_labels + label_height = field_height + + count = 0 + y_offset = @graph_height + y_label_offset( label_height ) + y_offset += font_size/1.2 unless rotate_y_labels + for label in get_y_labels + y = y_offset - (label_height * count) + x = rotate_y_labels ? 0 : -3 + + if stagger_y_labels and count % 2 == 1 + x -= stagger + @graph.add_element( "path", { + "d" => "M#{x} #{y} h#{stagger}", + "class" => "staggerGuideLine" + }) + end + + text = @graph.add_element( "text", { + "x" => x.to_s, + "y" => y.to_s, + "class" => "yAxisLabels" + }) + text.text = label.to_s + if rotate_y_labels + text.attributes["transform"] = "translate( -#{font_size} 0 ) "+ + "rotate( 90 #{x} #{y} ) " + text.attributes["style"] = "text-anchor: middle" + else + text.attributes["y"] = (y - (y_label_font_size/2)).to_s + text.attributes["style"] = "text-anchor: end" + end + draw_y_guidelines( label_height, count ) if show_y_guidelines + count += 1 + end + end + end + + + # Draws the X axis guidelines + def draw_x_guidelines( label_height, count ) + if count != 0 + @graph.add_element( "path", { + "d" => "M#{label_height*count} 0 v#@graph_height", + "class" => "guideLines" + }) + end + end + + + # Draws the Y axis guidelines + def draw_y_guidelines( label_height, count ) + if count != 0 + @graph.add_element( "path", { + "d" => "M0 #{@graph_height-(label_height*count)} h#@graph_width", + "class" => "guideLines" + }) + end + end + + + # Draws the graph title and subtitle + def draw_titles + if show_graph_title + @root.add_element( "text", { + "x" => (width / 2).to_s, + "y" => (title_font_size).to_s, + "class" => "mainTitle" + }).text = graph_title.to_s + end + + if show_graph_subtitle + y_subtitle = show_graph_title ? + title_font_size + 10 : + subtitle_font_size + @root.add_element("text", { + "x" => (width / 2).to_s, + "y" => (y_subtitle).to_s, + "class" => "subTitle" + }).text = graph_subtitle.to_s + end + + if show_x_title + y = @graph_height + @border_top + x_title_font_size + if show_x_labels + y += x_label_font_size + 5 if stagger_x_labels + y += x_label_font_size + 5 + end + x = width / 2 + + @root.add_element("text", { + "x" => x.to_s, + "y" => y.to_s, + "class" => "xAxisTitle", + }).text = x_title.to_s + end + + if show_y_title + x = y_title_font_size + (y_title_text_direction==:bt ? 3 : -3) + y = height / 2 + + text = @root.add_element("text", { + "x" => x.to_s, + "y" => y.to_s, + "class" => "yAxisTitle", + }) + text.text = y_title.to_s + if y_title_text_direction == :bt + text.attributes["transform"] = "rotate( -90, #{x}, #{y} )" + else + text.attributes["transform"] = "rotate( 90, #{x}, #{y} )" + end + end + end + + def keys + return @data.collect{ |d| d[:title] } + end + + # Draws the legend on the graph + def draw_legend + if key + group = @root.add_element( "g" ) + + key_count = 0 + for key_name in keys + y_offset = (KEY_BOX_SIZE * key_count) + (key_count * 5) + group.add_element( "rect", { + "x" => 0.to_s, + "y" => y_offset.to_s, + "width" => KEY_BOX_SIZE.to_s, + "height" => KEY_BOX_SIZE.to_s, + "class" => "key#{key_count+1}" + }) + group.add_element( "text", { + "x" => (KEY_BOX_SIZE + 5).to_s, + "y" => (y_offset + KEY_BOX_SIZE).to_s, + "class" => "keyText" + }).text = key_name.to_s + key_count += 1 + end + + case key_position + when :right + x_offset = @graph_width + @border_left + 10 + y_offset = @border_top + 20 + when :bottom + x_offset = @border_left + 20 + y_offset = @border_top + @graph_height + 5 + if show_x_labels + max_x_label_height_px = (not rotate_x_labels) ? + x_label_font_size : + get_x_labels.max{|a,b| + a.to_s.length<=>b.to_s.length + }.to_s.length * x_label_font_size * 0.6 + x_label_font_size + y_offset += max_x_label_height_px + y_offset += max_x_label_height_px + 5 if stagger_x_labels + end + y_offset += x_title_font_size + 5 if show_x_title + end + group.attributes["transform"] = "translate(#{x_offset} #{y_offset})" + end + end + + + private + + def sort_multiple( arrys, lo=0, hi=arrys[0].length-1 ) + if lo < hi + p = partition(arrys,lo,hi) + sort_multiple(arrys, lo, p-1) + sort_multiple(arrys, p+1, hi) + end + arrys + end + + def partition( arrys, lo, hi ) + p = arrys[0][lo] + l = lo + z = lo+1 + while z <= hi + if arrys[0][z] < p + l += 1 + arrys.each { |arry| arry[z], arry[l] = arry[l], arry[z] } + end + z += 1 + end + arrys.each { |arry| arry[lo], arry[l] = arry[l], arry[lo] } + l + end + + def style + if no_css + styles = parse_css + @root.elements.each("//*[@class]") { |el| + cl = el.attributes["class"] + style = styles[cl] + style += el.attributes["style"] if el.attributes["style"] + el.attributes["style"] = style + } + end + end + + def parse_css + css = get_style + rv = {} + while css =~ /^(\.(\w+)(?:\s*,\s*\.\w+)*)\s*\{/m + names_orig = names = $1 + css = $' + css =~ /([^}]+)\}/m + content = $1 + css = $' + + nms = [] + while names =~ /^\s*,?\s*\.(\w+)/ + nms << $1 + names = $' + end + + content = content.tr( "\n\t", " ") + for name in nms + current = rv[name] + current = current ? current+"; "+content : content + rv[name] = current.strip.squeeze(" ") + end + end + return rv + end + + + # Override and place code to add defs here + def add_defs defs + end + + + def start_svg + # Base document + @doc = Document.new + @doc << XMLDecl.new + @doc << DocType.new( %q{svg PUBLIC "-//W3C//DTD SVG 1.0//EN" } + + %q{"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"} ) + if style_sheet && style_sheet != '' + @doc << Instruction.new( "xml-stylesheet", + %Q{href="#{style_sheet}" type="text/css"} ) + end + @root = @doc.add_element( "svg", { + "width" => width.to_s, + "height" => height.to_s, + "viewBox" => "0 0 #{width} #{height}", + "xmlns" => "http://www.w3.org/2000/svg", + "xmlns:xlink" => "http://www.w3.org/1999/xlink", + "xmlns:a3" => "http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/", + "a3:scriptImplementation" => "Adobe" + }) + @root << Comment.new( " "+"\\"*66 ) + @root << Comment.new( " Created with SVG::Graph " ) + @root << Comment.new( " SVG::Graph by Sean E. Russell " ) + @root << Comment.new( " Losely based on SVG::TT::Graph for Perl by"+ + " Leo Lapworth & Stephan Morgan " ) + @root << Comment.new( " "+"/"*66 ) + + defs = @root.add_element( "defs" ) + add_defs defs + if not(style_sheet && style_sheet != '') and !no_css + @root << Comment.new(" include default stylesheet if none specified ") + style = defs.add_element( "style", {"type"=>"text/css"} ) + style << CData.new( get_style ) + end + + @root << Comment.new( "SVG Background" ) + @root.add_element( "rect", { + "width" => width.to_s, + "height" => height.to_s, + "x" => "0", + "y" => "0", + "class" => "svgBackground" + }) + end + + + def calculate_graph_dimensions + calculate_left_margin + calculate_right_margin + calculate_bottom_margin + calculate_top_margin + @graph_width = width - @border_left - @border_right + @graph_height = height - @border_top - @border_bottom + end + + def get_style + return < 500, + # :width => 300, + # :fields => fields, + # }) + # + # graph.add_data({ + # :data => data_sales_02, + # :title => 'Sales 2002', + # }) + # + # graph.add_data({ + # :data => data_sales_03, + # :title => 'Sales 2003', + # }) + # + # print "Content-type: image/svg+xml\r\n\r\n"; + # print graph.burn(); + # + # = Description + # + # This object aims to allow you to easily create high quality + # SVG line graphs. You can either use the default style sheet + # or supply your own. Either way there are many options which can + # be configured to give you control over how the graph is + # generated - with or without a key, data elements at each point, + # title, subtitle etc. + # + # = Examples + # + # http://www.germane-software/repositories/public/SVG/test/single.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. + # + # = See also + # + # * SVG::Graph::Graph + # * SVG::Graph::BarHorizontal + # * SVG::Graph::Bar + # * SVG::Graph::Pie + # * SVG::Graph::Plot + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class Line < SVG::Graph::Graph + # Show a small circle on the graph where the line + # goes from one point to the next. + attr_accessor :show_data_points + # Accumulates each data set. (i.e. Each point increased by sum of + # all previous series at same point). Default is 0, set to '1' to show. + attr_accessor :stacked + # Fill in the area under the plot if true + attr_accessor :area_fill + + # The constructor takes a hash reference, fields (the names for each + # field on the X axis) MUST be set, all other values are defaulted to + # those shown above - with the exception of style_sheet which defaults + # to using the internal style sheet. + def initialize config + raise "fields was not supplied or is empty" unless config[:fields] && + config[:fields].kind_of?(Array) && + config[:fields].length > 0 + super + end + + # In addition to the defaults set in Graph::initialize, sets + # [show_data_points] true + # [show_data_values] true + # [stacked] false + # [area_fill] false + def set_defaults + init_with( + :show_data_points => true, + :show_data_values => true, + :stacked => false, + :area_fill => false + ) + + self.top_align = self.top_font = self.right_align = self.right_font = 1 + end + + protected + + def max_value + max = 0 + + if (stacked == true) then + sums = Array.new(@config[:fields].length).fill(0) + + @data.each do |data| + sums.each_index do |i| + sums[i] += data[:data][i].to_f + end + end + + max = sums.max + else + max = @data.collect{|x| x[:data].max}.max + end + + return max + end + + def min_value + min = 0 + + if (min_scale_value.nil? == false) then + min = min_scale_value + elsif (stacked == true) then + min = @data[-1][:data].min + else + min = @data.collect{|x| x[:data].min}.min + end + + return min + end + + def get_x_labels + @config[:fields] + end + + def calculate_left_margin + super + label_left = @config[:fields][0].length / 2 * font_size * 0.6 + @border_left = label_left if label_left > @border_left + end + + def get_y_labels + maxvalue = max_value + minvalue = min_value + range = maxvalue - minvalue + top_pad = range == 0 ? 10 : range / 20.0 + scale_range = (maxvalue + top_pad) - minvalue + + scale_division = scale_divisions || (scale_range / 10.0) + + if scale_integers + scale_division = scale_division < 1 ? 1 : scale_division.round + end + + rv = [] + maxvalue = maxvalue%scale_division == 0 ? + maxvalue : maxvalue + scale_division + minvalue.step( maxvalue, scale_division ) {|v| rv << v} + return rv + end + + def calc_coords(field, value, width = field_width, height = field_height) + coords = {:x => 0, :y => 0} + coords[:x] = width * field + coords[:y] = @graph_height - value * height + + return coords + end + + def draw_data + minvalue = min_value + fieldheight = (@graph_height.to_f - font_size*2*top_font) / + (get_y_labels.max - get_y_labels.min) + fieldwidth = field_width + line = @data.length + + prev_sum = Array.new(@config[:fields].length).fill(0) + cum_sum = Array.new(@config[:fields].length).fill(-minvalue) + + for data in @data.reverse + lpath = "" + apath = "" + + if not stacked then cum_sum.fill(-minvalue) end + + data[:data].each_index do |i| + cum_sum[i] += data[:data][i] + + c = calc_coords(i, cum_sum[i], fieldwidth, fieldheight) + + lpath << "#{c[:x]} #{c[:y]} " + end + + if area_fill + if stacked then + (prev_sum.length - 1).downto 0 do |i| + c = calc_coords(i, prev_sum[i], fieldwidth, fieldheight) + + apath << "#{c[:x]} #{c[:y]} " + end + + c = calc_coords(0, prev_sum[0], fieldwidth, fieldheight) + else + apath = "V#@graph_height" + c = calc_coords(0, 0, fieldwidth, fieldheight) + end + + @graph.add_element("path", { + "d" => "M#{c[:x]} #{c[:y]} L" + lpath + apath + "Z", + "class" => "fill#{line}" + }) + end + + @graph.add_element("path", { + "d" => "M0 #@graph_height L" + lpath, + "class" => "line#{line}" + }) + + if show_data_points || show_data_values + cum_sum.each_index do |i| + if show_data_points + @graph.add_element( "circle", { + "cx" => (fieldwidth * i).to_s, + "cy" => (@graph_height - cum_sum[i] * fieldheight).to_s, + "r" => "2.5", + "class" => "dataPoint#{line}" + }) + end + make_datapoint_text( + fieldwidth * i, + @graph_height - cum_sum[i] * fieldheight - 6, + cum_sum[i] + minvalue + ) + end + end + + prev_sum = cum_sum.dup + line -= 1 + end + end + + + def get_css + return < 500, + # :width => 300, + # :fields => fields, + # }) + # + # graph.add_data({ + # :data => data_sales_02, + # :title => 'Sales 2002', + # }) + # + # print "Content-type: image/svg+xml\r\n\r\n" + # print graph.burn(); + # + # == Description + # + # This object aims to allow you to easily create high quality + # SVG pie graphs. You can either use the default style sheet + # or supply your own. Either way there are many options which can + # be configured to give you control over how the graph is + # generated - with or without a key, display percent on pie chart, + # title, subtitle etc. + # + # = Examples + # + # http://www.germane-software/repositories/public/SVG/test/single.rb + # + # == See also + # + # * SVG::Graph::Graph + # * SVG::Graph::BarHorizontal + # * SVG::Graph::Bar + # * SVG::Graph::Line + # * SVG::Graph::Plot + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class Pie < Graph + # Defaults are those set by Graph::initialize, and + # [show_shadow] true + # [shadow_offset] 10 + # [show_data_labels] false + # [show_actual_values] false + # [show_percent] true + # [show_key_data_labels] true + # [show_key_actual_values] true + # [show_key_percent] false + # [expanded] false + # [expand_greatest] false + # [expand_gap] 10 + # [show_x_labels] false + # [show_y_labels] false + # [datapoint_font_size] 12 + def set_defaults + init_with( + :show_shadow => true, + :shadow_offset => 10, + + :show_data_labels => false, + :show_actual_values => false, + :show_percent => true, + + :show_key_data_labels => true, + :show_key_actual_values => true, + :show_key_percent => false, + + :expanded => false, + :expand_greatest => false, + :expand_gap => 10, + + :show_x_labels => false, + :show_y_labels => false, + :datapoint_font_size => 12 + ) + @data = [] + end + + # Adds a data set to the graph. + # + # graph.add_data( { :data => [1,2,3,4] } ) + # + # Note that the :title is not necessary. If multiple + # data sets are added to the graph, the pie chart will + # display the +sums+ of the data. EG: + # + # graph.add_data( { :data => [1,2,3,4] } ) + # graph.add_data( { :data => [2,3,5,9] } ) + # + # is the same as: + # + # graph.add_data( { :data => [3,5,8,13] } ) + def add_data arg + arg[:data].each_index {|idx| + @data[idx] = 0 unless @data[idx] + @data[idx] += arg[:data][idx] + } + end + + # If true, displays a drop shadow for the chart + attr_accessor :show_shadow + # Sets the offset of the shadow from the pie chart + attr_accessor :shadow_offset + # If true, display the data labels on the chart + attr_accessor :show_data_labels + # If true, display the actual field values in the data labels + attr_accessor :show_actual_values + # If true, display the percentage value of each pie wedge in the data + # labels + attr_accessor :show_percent + # If true, display the labels in the key + attr_accessor :show_key_data_labels + # If true, display the actual value of the field in the key + attr_accessor :show_key_actual_values + # If true, display the percentage value of the wedges in the key + attr_accessor :show_key_percent + # If true, "explode" the pie (put space between the wedges) + attr_accessor :expanded + # If true, expand the largest pie wedge + attr_accessor :expand_greatest + # The amount of space between expanded wedges + attr_accessor :expand_gap + # The font size of the data point labels + attr_accessor :datapoint_font_size + + + protected + + def add_defs defs + gradient = defs.add_element( "filter", { + "id"=>"dropshadow", + "width" => "1.2", + "height" => "1.2", + } ) + gradient.add_element( "feGaussianBlur", { + "stdDeviation" => "4", + "result" => "blur" + }) + end + + # We don't need the graph + def draw_graph + end + + def get_y_labels + [""] + end + + def get_x_labels + [""] + end + + def keys + total = 0 + max_value = 0 + @data.each {|x| total += x } + percent_scale = 100.0 / total + count = -1 + a = @config[:fields].collect{ |x| + count += 1 + v = @data[count] + perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : "" + x + " [" + v.to_s + "]" + perc + } + end + + RADIANS = Math::PI/180 + + def draw_data + @graph = @root.add_element( "g" ) + background = @graph.add_element("g") + midground = @graph.add_element("g") + + diameter = @graph_height > @graph_width ? @graph_width : @graph_height + diameter -= expand_gap if expanded or expand_greatest + diameter -= datapoint_font_size if show_data_labels + diameter -= 10 if show_shadow + radius = diameter / 2.0 + + xoff = (width - diameter) / 2 + yoff = (height - @border_bottom - diameter) + yoff -= 10 if show_shadow + @graph.attributes['transform'] = "translate( #{xoff} #{yoff} )" + + wedge_text_pad = 5 + wedge_text_pad = 20 if show_percent and show_data_labels + + total = 0 + max_value = 0 + @data.each {|x| + max_value = max_value < x ? x : max_value + total += x + } + percent_scale = 100.0 / total + + prev_percent = 0 + rad_mult = 3.6 * RADIANS + @config[:fields].each_index { |count| + value = @data[count] + percent = percent_scale * value + + radians = prev_percent * rad_mult + x_start = radius+(Math.sin(radians) * radius) + y_start = radius-(Math.cos(radians) * radius) + radians = (prev_percent+percent) * rad_mult + x_end = radius+(Math.sin(radians) * radius) + x_end -= 0.00001 if @data.length == 1 + y_end = radius-(Math.cos(radians) * radius) + path = "M#{radius},#{radius} L#{x_start},#{y_start} "+ + "A#{radius},#{radius} "+ + "0, #{percent >= 50 ? '1' : '0'},1, "+ + "#{x_end} #{y_end} Z" + + + wedge = @foreground.add_element( "path", { + "d" => path, + "class" => "fill#{count+1}" + }) + + translate = nil + tx = 0 + ty = 0 + half_percent = prev_percent + percent / 2 + radians = half_percent * rad_mult + + if show_shadow + shadow = background.add_element( "path", { + "d" => path, + "filter" => "url(#dropshadow)", + "style" => "fill: #ccc; stroke: none;" + }) + clear = midground.add_element( "path", { + "d" => path, + "style" => "fill: #fff; stroke: none;" + }) + end + + if expanded or (expand_greatest && value == max_value) + tx = (Math.sin(radians) * expand_gap) + ty = -(Math.cos(radians) * expand_gap) + translate = "translate( #{tx} #{ty} )" + wedge.attributes["transform"] = translate + clear.attributes["transform"] = translate if clear + end + + if show_shadow + shadow.attributes["transform"] = + "translate( #{tx+shadow_offset} #{ty+shadow_offset} )" + end + + if show_data_labels and value != 0 + label = "" + label += @config[:fields][count] if show_key_data_labels + label += " ["+value.to_s+"]" if show_actual_values + label += " "+percent.round.to_s+"%" if show_percent + + msr = Math.sin(radians) + mcr = Math.cos(radians) + tx = radius + (msr * radius) + ty = radius -(mcr * radius) + + if expanded or (expand_greatest && value == max_value) + tx += (msr * expand_gap) + ty -= (mcr * expand_gap) + end + @foreground.add_element( "text", { + "x" => tx.to_s, + "y" => ty.to_s, + "class" => "dataPointLabel", + "style" => "stroke: #fff; stroke-width: 2;" + }).text = label.to_s + @foreground.add_element( "text", { + "x" => tx.to_s, + "y" => ty.to_s, + "class" => "dataPointLabel", + }).text = label.to_s + end + + prev_percent += percent + } + end + + + def round val, to + up = 10**to.to_f + (val * up).to_i / up + end + + + def get_css + return < 500, + # :width => 300, + # :key => true, + # :scale_x_integers => true, + # :scale_y_integerrs => true, + # }) + # + # graph.add_data({ + # :data => projection + # :title => 'Projected', + # }) + # + # graph.add_data({ + # :data => actual, + # :title => 'Actual', + # }) + # + # print graph.burn() + # + # = Description + # + # Produces a graph of scalar data. + # + # This object aims to allow you to easily create high quality + # SVG[http://www.w3c.org/tr/svg] scalar plots. You can either use the + # default style sheet or supply your own. Either way there are many options + # which can be configured to give you control over how the graph is + # generated - with or without a key, data elements at each point, title, + # subtitle etc. + # + # = Examples + # + # http://www.germane-software/repositories/public/SVG/test/plot.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: + # + # [ 1, 2 ] # A data set with 1 point: (1,2) + # [ 1,2, 5,6] # A data set with 2 points: (1,2) and (5,6) + # + # = See also + # + # * SVG::Graph::Graph + # * SVG::Graph::BarHorizontal + # * SVG::Graph::Bar + # * SVG::Graph::Line + # * SVG::Graph::Pie + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class Plot < Graph + + # In addition to the defaults set by Graph::initialize, sets + # [show_data_values] true + # [show_data_points] true + # [area_fill] false + # [stacked] false + def set_defaults + init_with( + :show_data_values => true, + :show_data_points => true, + :area_fill => false, + :stacked => false + ) + self.top_align = self.right_align = self.top_font = self.right_font = 1 + end + + # Determines the scaling for the X axis divisions. + # + # graph.scale_x_divisions = 2 + # + # would cause the graph to attempt to generate labels stepped by 2; EG: + # 0,2,4,6,8... + attr_accessor :scale_x_divisions + # Determines the scaling for the Y axis divisions. + # + # graph.scale_y_divisions = 0.5 + # + # would cause the graph to attempt to generate labels stepped by 0.5; EG: + # 0, 0.5, 1, 1.5, 2, ... + attr_accessor :scale_y_divisions + # Make the X axis labels integers + attr_accessor :scale_x_integers + # Make the Y axis labels integers + attr_accessor :scale_y_integers + # Fill the area under the line + attr_accessor :area_fill + # Show a small circle on the graph where the line + # goes from one point to the next. + attr_accessor :show_data_points + # Set the minimum value of the X axis + attr_accessor :min_x_value + # Set the minimum value of the Y axis + attr_accessor :min_y_value + + + # Adds data to the plot. The data must be in X,Y pairs; EG + # [ 1, 2 ] # A data set with 1 point: (1,2) + # [ 1,2, 5,6] # A data set with 2 points: (1,2) and (5,6) + def add_data data + @data = [] unless @data + + raise "No data provided by #{conf.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| + (i%2 == 0 ? x : y) << data[:data][i] + } + sort( x, y ) + data[:data] = [x,y] + @data << data + end + + + protected + + def keys + @data.collect{ |x| x[:title] } + end + + def calculate_left_margin + super + label_left = get_x_labels[0].to_s.length / 2 * font_size * 0.6 + @border_left = label_left if label_left > @border_left + end + + def calculate_right_margin + super + label_right = get_x_labels[-1].to_s.length / 2 * font_size * 0.6 + @border_right = label_right if label_right > @border_right + end + + + X = 0 + Y = 1 + def x_range + max_value = @data.collect{|x| x[:data][X][-1] }.max + min_value = @data.collect{|x| x[:data][X][0] }.min + min_value = min_value "M#{x_start} #@graph_height #{lpath} V#@graph_height Z", + "class" => "fill#{line}" + }) + end + + @graph.add_element( "path", { + "d" => "M#{x_start} #{y_start} #{lpath}", + "class" => "line#{line}" + }) + + if show_data_points || show_data_values + x_points.each_index { |idx| + x = (x_points[idx] - x_min) * x_step + y = @graph_height - (y_points[idx] - y_min) * y_step + if show_data_points + @graph.add_element( "circle", { + "cx" => x.to_s, + "cy" => y.to_s, + "r" => "2.5", + "class" => "dataPoint#{line}" + }) + add_popup(x, y, format( x_points[idx], y_points[idx] )) if add_popups + end + make_datapoint_text( x, y-6, y_points[idx] ) if show_data_values + } + end + line += 1 + end + end + + def format x, y + "(#{(x * 100).to_i / 100}, #{(y * 100).to_i / 100})" + end + + def get_css + return < 640, + # :height => 480, + # :graph_title => title, + # :show_graph_title => true, + # :no_css => 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", + # :stagger_x_labels => true, + # :stagger_y_labels => true, + # :x_label_format => "%m/%d/%y", + # }) + # + # graph.add_data({ + # :data => data1, + # :title => 'Data', + # }) + # + # print graph.burn() + # + # = Description + # + # Produces a graph of temporal scalar data. + # + # = Examples + # + # http://www.germane-software/repositories/public/SVG/test/schedule.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. + # + # 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 + # * SVG::Graph::TimeSeries + # + # == Author + # + # Sean E. Russell + # + # Copyright 2004 Sean E. Russell + # This software is available under the Ruby license[LICENSE.txt] + # + class Schedule < Graph + # 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 + init_with( + :x_label_format => '%Y-%m-%d %H:%M:%S', + :popup_format => '%Y-%m-%d %H:%M:%S', + :scale_x_divisions => false, + :scale_x_integers => false, + :bar_gap => true + ) + 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 + attr_accessor :min_x_value + attr_accessor :scale_x_divisions + attr_accessor :scale_x_integers + attr_accessor :bar_gap + + # Add data to the plot. + # + # # A data set with 1 point: Lunch from 12:30 to 14:00 + # d1 = [ "Lunch", "12:30", "14:00" ] + # # A data set with 2 points: "Cats" runs from 5/11/03 to 7/15/04, and + # # "Henry V" runs from 6/12/03 to 8/20/03 + # d2 = [ "Cats", "5/11/03", "7/15/04", + # "Henry V", "6/12/03", "8/20/03" ] + # + # graph.add_data( + # :data => d1, + # :title => 'Meetings' + # ) + # graph.add_data( + # :data => d2, + # :title => 'Plays' + # ) + # + # Note that the data must be in time,value pairs, and that the date format + # may be any date that is parseable by ParseDate. + # Also note that, in this example, we're mixing scales; the data from d1 + # will probably not be discernable if both data sets are plotted on the same + # graph, since d1 is too granular. + def add_data data + @data = [] unless @data + + raise "No data provided by #{conf.inspect}" unless data[:data] and + data[:data].kind_of? Array + raise "Data supplied must be title,from,to tripples! "+ + "The data provided contained an odd set of "+ + "data points" unless data[:data].length % 3 == 0 + return if data[:data].length == 0 + + + y = [] + x_start = [] + x_end = [] + data[:data].each_index {|i| + im3 = i%3 + if im3 == 0 + y << data[:data][i] + else + arr = ParseDate.parsedate( data[:data][i] ) + t = Time.local( *arr[0,6].compact ) + (im3 == 1 ? x_start : x_end) << t.to_i + end + } + sort( x_start, x_end, y ) + @data = [x_start, x_end, y ] + 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 + rv = get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) } + end + + def y_label_offset( height ) + height / -2.0 + end + + def get_y_labels + @data[2] + end + + def draw_data + fieldheight = field_height + fieldwidth = field_width + + bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0 + subbar_height = fieldheight - bargap + + field_count = 1 + y_mod = (subbar_height / 2) + (font_size / 2) + min,max,div = x_range + scale = (@graph_width.to_f - font_size*2) / (max-min) + @data[0].each_index { |i| + x_start = @data[0][i] + x_end = @data[1][i] + y = @graph_height - (fieldheight * field_count) + bar_width = (x_end-x_start) * scale + bar_start = x_start * scale - (min * scale) + + @graph.add_element( "rect", { + "x" => bar_start.to_s, + "y" => y.to_s, + "width" => bar_width.to_s, + "height" => subbar_height.to_s, + "class" => "fill#{field_count+1}" + }) + field_count += 1 + } + end + + def get_css + return < 12 + arr[5] += (arr[4] / 12).to_i + arr[4] = (arr[4] % 12) + end + cur = Time.local(*arr).to_i + end + when "years" + cur = min + while cur < max + rv << cur + arr = Time.at( cur ).to_a + arr[5] += amount + cur = Time.local(*arr).to_i + end + when "weeks" + step = 7 * 24 * 60 * 60 * amount + when "days" + step = 24 * 60 * 60 * amount + when "hours" + step = 60 * 60 * amount + when "minutes" + step = 60 * amount + when "seconds" + 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 --git a/lib/SVG/Graph/TimeSeries.rb b/lib/SVG/Graph/TimeSeries.rb new file mode 100644 index 000000000..3f45b291d --- /dev/null +++ b/lib/SVG/Graph/TimeSeries.rb @@ -0,0 +1,238 @@ +require 'SVG/Graph/Plot' + +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 + # + # 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 + t = DateTime.parse( data[:data][i] ).to_time + 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) + @min_x_value = DateTime.parse( value ).to_time + 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 --git a/lib/SVG/LICENSE.txt b/lib/SVG/LICENSE.txt new file mode 100644 index 000000000..2b945d276 --- /dev/null +++ b/lib/SVG/LICENSE.txt @@ -0,0 +1,57 @@ +SVG::Graph is copyrighted free software by Sean Russell . +You can redistribute it and/or modify it under either the terms of the GPL +(see GPL.txt file), 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. + + All files of this sort are located under the contrib/ 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 --git a/lib/diff.rb b/lib/diff.rb new file mode 100644 index 000000000..9e1653f14 --- /dev/null +++ b/lib/diff.rb @@ -0,0 +1,282 @@ +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 --git a/lib/generators/redmine_plugin/USAGE b/lib/generators/redmine_plugin/USAGE new file mode 100644 index 000000000..793f2fc5e --- /dev/null +++ b/lib/generators/redmine_plugin/USAGE @@ -0,0 +1,26 @@ +Description: + The plugin generator creates stubs for a new Redmine plugin. + +Example: + ./script/rails generate redmine_plugin meetings + create plugins/meetings/app + create plugins/meetings/app/controllers + create plugins/meetings/app/helpers + create plugins/meetings/app/models + create plugins/meetings/app/views + create plugins/meetings/db/migrate + create plugins/meetings/lib/tasks + create plugins/meetings/assets/images + create plugins/meetings/assets/javascripts + create plugins/meetings/assets/stylesheets + create plugins/meetings/config/locales + create plugins/meetings/test + create plugins/meetings/test/fixtures + create plugins/meetings/test/unit + create plugins/meetings/test/functional + create plugins/meetings/test/integration + create plugins/meetings/README.rdoc + create plugins/meetings/init.rb + create plugins/meetings/config/routes.rb + create plugins/meetings/config/locales/en.yml + create plugins/meetings/test/test_helper.rb diff --git a/lib/generators/redmine_plugin/redmine_plugin_generator.rb b/lib/generators/redmine_plugin/redmine_plugin_generator.rb new file mode 100644 index 000000000..562366342 --- /dev/null +++ b/lib/generators/redmine_plugin/redmine_plugin_generator.rb @@ -0,0 +1,37 @@ +class RedminePluginGenerator < Rails::Generators::NamedBase + source_root File.expand_path("../templates", __FILE__) + + attr_reader :plugin_path, :plugin_name, :plugin_pretty_name + + def initialize(*args) + super + @plugin_name = file_name.underscore + @plugin_pretty_name = plugin_name.titleize + @plugin_path = "plugins/#{plugin_name}" + end + + def copy_templates + empty_directory "#{plugin_path}/app" + empty_directory "#{plugin_path}/app/controllers" + empty_directory "#{plugin_path}/app/helpers" + empty_directory "#{plugin_path}/app/models" + empty_directory "#{plugin_path}/app/views" + empty_directory "#{plugin_path}/db/migrate" + empty_directory "#{plugin_path}/lib/tasks" + empty_directory "#{plugin_path}/assets/images" + empty_directory "#{plugin_path}/assets/javascripts" + empty_directory "#{plugin_path}/assets/stylesheets" + empty_directory "#{plugin_path}/config/locales" + empty_directory "#{plugin_path}/test" + empty_directory "#{plugin_path}/test/fixtures" + empty_directory "#{plugin_path}/test/unit" + empty_directory "#{plugin_path}/test/functional" + empty_directory "#{plugin_path}/test/integration" + + template 'README.rdoc', "#{plugin_path}/README.rdoc" + template 'init.rb.erb', "#{plugin_path}/init.rb" + template 'routes.rb', "#{plugin_path}/config/routes.rb" + template 'en_rails_i18n.yml', "#{plugin_path}/config/locales/en.yml" + template 'test_helper.rb.erb', "#{plugin_path}/test/test_helper.rb" + end +end diff --git a/lib/generators/redmine_plugin/templates/README.rdoc b/lib/generators/redmine_plugin/templates/README.rdoc new file mode 100644 index 000000000..7a31a890e --- /dev/null +++ b/lib/generators/redmine_plugin/templates/README.rdoc @@ -0,0 +1,3 @@ += <%= file_name %> + +Description goes here diff --git a/lib/generators/redmine_plugin/templates/en_rails_i18n.yml b/lib/generators/redmine_plugin/templates/en_rails_i18n.yml new file mode 100644 index 000000000..642b07f82 --- /dev/null +++ b/lib/generators/redmine_plugin/templates/en_rails_i18n.yml @@ -0,0 +1,3 @@ +# English strings go here for Rails i18n +en: + # my_label: "My label" diff --git a/lib/generators/redmine_plugin/templates/init.rb.erb b/lib/generators/redmine_plugin/templates/init.rb.erb new file mode 100644 index 000000000..763ba7d22 --- /dev/null +++ b/lib/generators/redmine_plugin/templates/init.rb.erb @@ -0,0 +1,8 @@ +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 --git a/lib/generators/redmine_plugin/templates/routes.rb b/lib/generators/redmine_plugin/templates/routes.rb new file mode 100644 index 000000000..1803173d0 --- /dev/null +++ b/lib/generators/redmine_plugin/templates/routes.rb @@ -0,0 +1,2 @@ +# Plugin's routes +# See: http://guides.rubyonrails.org/routing.html diff --git a/lib/generators/redmine_plugin/templates/test_helper.rb.erb b/lib/generators/redmine_plugin/templates/test_helper.rb.erb new file mode 100644 index 000000000..54685d33c --- /dev/null +++ b/lib/generators/redmine_plugin/templates/test_helper.rb.erb @@ -0,0 +1,2 @@ +# Load the Redmine helper +require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper') diff --git a/lib/generators/redmine_plugin_controller/USAGE b/lib/generators/redmine_plugin_controller/USAGE new file mode 100644 index 000000000..adc3f82b3 --- /dev/null +++ b/lib/generators/redmine_plugin_controller/USAGE @@ -0,0 +1,5 @@ +Description: + Generates a plugin controller. + +Example: + ./script/rails generate redmine_plugin_controller meetings pools index show vote diff --git a/lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb b/lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb new file mode 100644 index 000000000..8351ce681 --- /dev/null +++ b/lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb @@ -0,0 +1,27 @@ +class RedminePluginControllerGenerator < Rails::Generators::NamedBase + source_root File.expand_path("../templates", __FILE__) + argument :controller, :type => :string + argument :actions, :type => :array, :default => [], :banner => "ACTION ACTION ..." + + attr_reader :plugin_path, :plugin_name, :plugin_pretty_name + + def initialize(*args) + super + @plugin_name = file_name.underscore + @plugin_pretty_name = plugin_name.titleize + @plugin_path = "plugins/#{plugin_name}" + @controller_class = controller.camelize + end + + def copy_templates + template 'controller.rb.erb', "#{plugin_path}/app/controllers/#{controller}_controller.rb" + template 'helper.rb.erb', "#{plugin_path}/app/helpers/#{controller}_helper.rb" + template 'functional_test.rb.erb', "#{plugin_path}/test/functional/#{controller}_controller_test.rb" + # View template for each action. + actions.each do |action| + path = "#{plugin_path}/app/views/#{controller}/#{action}.html.erb" + @action_name = action + template 'view.html.erb', path + end + end +end diff --git a/lib/generators/redmine_plugin_controller/templates/controller.rb.erb b/lib/generators/redmine_plugin_controller/templates/controller.rb.erb new file mode 100644 index 000000000..dddbf7017 --- /dev/null +++ b/lib/generators/redmine_plugin_controller/templates/controller.rb.erb @@ -0,0 +1,9 @@ +class <%= @controller_class %>Controller < ApplicationController + unloadable + +<% actions.each do |action| -%> + + def <%= action %> + end +<% end -%> +end diff --git a/lib/generators/redmine_plugin_controller/templates/functional_test.rb.erb b/lib/generators/redmine_plugin_controller/templates/functional_test.rb.erb new file mode 100644 index 000000000..0499b6970 --- /dev/null +++ b/lib/generators/redmine_plugin_controller/templates/functional_test.rb.erb @@ -0,0 +1,8 @@ +require File.expand_path('../../test_helper', __FILE__) + +class <%= @controller_class %>ControllerTest < ActionController::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/lib/generators/redmine_plugin_controller/templates/helper.rb.erb b/lib/generators/redmine_plugin_controller/templates/helper.rb.erb new file mode 100644 index 000000000..059e12f3b --- /dev/null +++ b/lib/generators/redmine_plugin_controller/templates/helper.rb.erb @@ -0,0 +1,2 @@ +module <%= @controller_class %>Helper +end diff --git a/lib/generators/redmine_plugin_controller/templates/view.html.erb b/lib/generators/redmine_plugin_controller/templates/view.html.erb new file mode 100644 index 000000000..21d5b645a --- /dev/null +++ b/lib/generators/redmine_plugin_controller/templates/view.html.erb @@ -0,0 +1 @@ +

    #{ after }", false ) + end + end + + def lT( text ) + text =~ /\#$/ ? 'o' : 'u' + end + + def hard_break( text ) + text.gsub!( /(.)\n(?!\Z| *([#*=]+(\s|$)|[{|]))/, "\\1
    " ) 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
    #{ blk }
    " + else + blk = "\t

    #{ blk }

    " + 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\n\t\t#{ content }

    \n\t" + end + + def textile_p( tag, atts, cite, content ) + atts = shelve( atts ) if atts + "\t<#{ tag }#{ atts }>#{ content }" + end + + alias textile_h1 textile_p + alias textile_h3 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 = "#{ num } #{ content }" + atts = shelve( atts ) if atts + "\t#{ content }

    " + 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; "h3"; end + blk, cont = "<#{ tag }>#{ $1 }", $' + 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 }\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" ) + "
    \n#{ blk }\n
    \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| + "
    " + 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 }#{ oqa }" + + end + end + end + + LINK_RE = / + ( + ([\s\[{(]|[#{PUNCT}])? # $pre + " # start + (#{C}) # $atts + ([^"\n]+?) # $text + \s? + (?:\(([^)]+?)\)(?="))? # $title + ": + ( # $url + (\/|[a-zA-Z]+:\/\/|www\.|mailto:) # $proto + [[:alnum:]_\/]\S+? + ) + (\/)? # $slash + ([^[:alnum:]_\=\/;\(\)]*?) # $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?('
    ') + 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 }#{ text }#{ 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 ) + + "#{ text }" + 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 ) + + "#{ text }" + end + end + + TEXTILE_REFS_RE = /(^ *)\[([^\[\n]+?)\](#{HYPERLINK})(?=\s|$)/ + MARKDOWN_REFS_RE = /(^ *)\[([^\n]+?)\]:\s+?(?:\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 << "" if href + out << "" + out << "#{ href_a1 }#{ href_a2 }" if href + + if algn + algn = h_align( algn ) + if stln == "

    " + out = "

    #{ out }" + else + out = "#{ stln }

    #{ out }
    " + 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\2\3' ) + text.gsub!( /^ *==([^=]+.*?)==/m, + '\1\2\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)?/, + '\1\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 ,
     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 
     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 : /\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(//)
    +                        line = ""
    +                        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 
     content
    +            text.gsub!( // ) { @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 )
    +        ' ' + name + '
    ' + 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, + 'h3' => nil, + 'h3' => nil, + 'h4' => nil, + 'h5' => nil, + 'h6' => nil, + 'blockquote' => ['cite'] + } + + def clean_html( text, tags = BASIC_TAGS ) + text.gsub!( /]*)>/ ) 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}" : "<#{$1}#{'>' unless $3.blank?}" } + end +end + diff --git a/lib/redmine.rb b/lib/redmine.rb new file mode 100644 index 000000000..a2a9ba40b --- /dev/null +++ b/lib/redmine.rb @@ -0,0 +1,300 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# 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 +#by young +Redmine::MenuManager.map :top_menu do |menu| + menu.push :home, :home_path + menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural + menu.push :requirement, {:controller => 'bids', :action => 'index'} + menu.push :developer, {:controller => 'users', :action => 'index'} + menu.push :investor, :home_path + menu.push :theme, :home_path +# menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? } +# 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 +#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 +########fq +Redmine::MenuManager.map :bid_menu do |menu| + menu.push :respond, { :controller => 'bids', :action => 'show' }, :caption => :label_user_response + menu.push :project, { :controller => 'bids', :action => 'show_project' }, :caption => :label_bidding_project +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 +#added by young +Redmine::MenuManager.map :user_menu do |menu| + menu.push :activity, {:controller => 'users', :action => 'show' } + menu.push :project, {:controller => 'users', :action => 'user_projects'} + menu.push :requirement_focus, {} + menu.push :user_newfeedback, {:controller => 'users', :action => 'user_newfeedback'} +end +#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 --git a/lib/redmine/access_control.rb b/lib/redmine/access_control.rb new file mode 100644 index 000000000..7c4a5a5ec --- /dev/null +++ b/lib/redmine/access_control.rb @@ -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 --git a/lib/redmine/access_keys.rb b/lib/redmine/access_keys.rb new file mode 100644 index 000000000..c2f6157d8 --- /dev/null +++ b/lib/redmine/access_keys.rb @@ -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 --git a/lib/redmine/activity.rb b/lib/redmine/activity.rb new file mode 100644 index 000000000..27ff52eb7 --- /dev/null +++ b/lib/redmine/activity.rb @@ -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 --git a/lib/redmine/activity/fetcher.rb b/lib/redmine/activity/fetcher.rb new file mode 100644 index 000000000..9ce12e0da --- /dev/null +++ b/lib/redmine/activity/fetcher.rb @@ -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 --git a/lib/redmine/ciphering.rb b/lib/redmine/ciphering.rb new file mode 100644 index 000000000..c691e23ee --- /dev/null +++ b/lib/redmine/ciphering.rb @@ -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 --git a/lib/redmine/codeset_util.rb b/lib/redmine/codeset_util.rb new file mode 100644 index 000000000..45a5c3524 --- /dev/null +++ b/lib/redmine/codeset_util.rb @@ -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 --git a/lib/redmine/configuration.rb b/lib/redmine/configuration.rb new file mode 100644 index 000000000..6723b777e --- /dev/null +++ b/lib/redmine/configuration.rb @@ -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: + # * :file: the configuration file to load (default: config/configuration.yml) + # * :env: 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 --git a/lib/redmine/core_ext.rb b/lib/redmine/core_ext.rb new file mode 100644 index 000000000..573313e74 --- /dev/null +++ b/lib/redmine/core_ext.rb @@ -0,0 +1 @@ +Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) } diff --git a/lib/redmine/core_ext/active_record.rb b/lib/redmine/core_ext/active_record.rb new file mode 100644 index 000000000..ad27a3f03 --- /dev/null +++ b/lib/redmine/core_ext/active_record.rb @@ -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 --git a/lib/redmine/core_ext/date.rb b/lib/redmine/core_ext/date.rb new file mode 100644 index 000000000..9244b5d6e --- /dev/null +++ b/lib/redmine/core_ext/date.rb @@ -0,0 +1,5 @@ +require File.dirname(__FILE__) + '/date/calculations' + +class Date #:nodoc: + include Redmine::CoreExtensions::Date::Calculations +end diff --git a/lib/redmine/core_ext/date/calculations.rb b/lib/redmine/core_ext/date/calculations.rb new file mode 100644 index 000000000..0372e8ac1 --- /dev/null +++ b/lib/redmine/core_ext/date/calculations.rb @@ -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 --git a/lib/redmine/core_ext/string.rb b/lib/redmine/core_ext/string.rb new file mode 100644 index 000000000..c865284ac --- /dev/null +++ b/lib/redmine/core_ext/string.rb @@ -0,0 +1,11 @@ +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 + + def is_binary_data? + ( self.count( "^ -~", "^\r\n" ).fdiv(self.size) > 0.3 || self.index( "\x00" ) ) unless empty? + end +end diff --git a/lib/redmine/core_ext/string/conversions.rb b/lib/redmine/core_ext/string/conversions.rb new file mode 100644 index 000000000..7fbc02ee6 --- /dev/null +++ b/lib/redmine/core_ext/string/conversions.rb @@ -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 --git a/lib/redmine/core_ext/string/inflections.rb b/lib/redmine/core_ext/string/inflections.rb new file mode 100644 index 000000000..ecbbe2789 --- /dev/null +++ b/lib/redmine/core_ext/string/inflections.rb @@ -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 --git a/lib/redmine/custom_field_format.rb b/lib/redmine/custom_field_format.rb new file mode 100644 index 000000000..f7cd5d1c6 --- /dev/null +++ b/lib/redmine/custom_field_format.rb @@ -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 --git a/lib/redmine/default_data/loader.rb b/lib/redmine/default_data/loader.rb new file mode 100644 index 000000000..393738f93 --- /dev/null +++ b/lib/redmine/default_data/loader.rb @@ -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 --git a/lib/redmine/export/pdf.rb b/lib/redmine/export/pdf.rb new file mode 100644 index 000000000..139416798 --- /dev/null +++ b/lib/redmine/export/pdf.rb @@ -0,0 +1,807 @@ +# 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 = "" + rescue + txt + end || '' + super(txt) + end + + def textstring(s) + # Format a text string + if s =~ /^\{\{([<>]?)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 = "" + 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('<>') + out('endobj') + end + #Outline root + newobj() + @outlineRoot=self.n + out("<>"); + 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, 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, 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) + def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y, 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 --git a/lib/redmine/helpers/calendar.rb b/lib/redmine/helpers/calendar.rb new file mode 100644 index 000000000..fa01b2f42 --- /dev/null +++ b/lib/redmine/helpers/calendar.rb @@ -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 --git a/lib/redmine/helpers/diff.rb b/lib/redmine/helpers/diff.rb new file mode 100644 index 000000000..537bfa05d --- /dev/null +++ b/lib/redmine/helpers/diff.rb @@ -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] = ''.html_safe + words[add_at] + words[add_to] = words[add_to] + ''.html_safe + end + if del_at + words.insert del_at - del_off + dels + words_add, ''.html_safe + deleted + ''.html_safe + dels += 1 + del_off += words_del + words_del = 0 + end + end + words.join(' ').html_safe + end + end + end +end diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb new file mode 100644 index 000000000..32be436bd --- /dev/null +++ b/lib/redmine/helpers/gantt.rb @@ -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 + + # 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, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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 --git a/lib/redmine/helpers/time_report.rb b/lib/redmine/helpers/time_report.rb new file mode 100644 index 000000000..09093dc95 --- /dev/null +++ b/lib/redmine/helpers/time_report.rb @@ -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 --git a/lib/redmine/hook.rb b/lib/redmine/hook.rb new file mode 100644 index 000000000..e5a2695d1 --- /dev/null +++ b/lib/redmine/hook.rb @@ -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 --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb new file mode 100644 index 000000000..c5922d955 --- /dev/null +++ b/lib/redmine/i18n.rb @@ -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. currency.format is regarded the same as + # %w(currency format). + 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 --git a/lib/redmine/imap.rb b/lib/redmine/imap.rb new file mode 100644 index 000000000..6e15c57e6 --- /dev/null +++ b/lib/redmine/imap.rb @@ -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 --git a/lib/redmine/info.rb b/lib/redmine/info.rb new file mode 100644 index 000000000..98df8d20b --- /dev/null +++ b/lib/redmine/info.rb @@ -0,0 +1,29 @@ +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 + + def environment + s = "Environment:\n" + s << [ + ["Redmine version", Redmine::VERSION], + ["Ruby version", "#{RUBY_VERSION} (#{RUBY_PLATFORM})"], + ["Rails version", Rails::VERSION::STRING], + ["Environment", Rails.env], + ["Database adapter", ActiveRecord::Base.connection.adapter_name] + ].map {|info| " %-40s %s" % info}.join("\n") + s << "\nRedmine plugins:\n" + + plugins = Redmine::Plugin.all + if plugins.any? + s << plugins.map {|plugin| " %-40s %s" % [plugin.id.to_s, plugin.version.to_s]}.join("\n") + else + s << " no plugin installed" + end + end + end + end +end diff --git a/lib/redmine/menu_manager.rb b/lib/redmine/menu_manager.rb new file mode 100644 index 000000000..25974ed83 --- /dev/null +++ b/lib/redmine/menu_manager.rb @@ -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 << '
  • ' + # 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 << '
  • ' + 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 --git a/lib/redmine/mime_type.rb b/lib/redmine/mime_type.rb new file mode 100644 index 000000000..d902c995c --- /dev/null +++ b/lib/redmine/mime_type.rb @@ -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 --git a/lib/redmine/notifiable.rb b/lib/redmine/notifiable.rb new file mode 100644 index 000000000..88ca9d776 --- /dev/null +++ b/lib/redmine/notifiable.rb @@ -0,0 +1,26 @@ +module Redmine + class Notifiable < Struct.new(:name, :parent) + + def to_s + name + end + + # TODO: Plugin API for adding a new notification? + def self.all + notifications = [] + notifications << Notifiable.new('issue_added') + notifications << Notifiable.new('issue_updated') + notifications << Notifiable.new('issue_note_added', 'issue_updated') + notifications << Notifiable.new('issue_status_updated', 'issue_updated') + notifications << Notifiable.new('issue_priority_updated', 'issue_updated') + notifications << Notifiable.new('news_added') + notifications << Notifiable.new('news_comment_added') + notifications << Notifiable.new('document_added') + notifications << Notifiable.new('file_added') + notifications << Notifiable.new('message_posted') + notifications << Notifiable.new('wiki_content_added') + notifications << Notifiable.new('wiki_content_updated') + notifications + end + end +end diff --git a/lib/redmine/pagination.rb b/lib/redmine/pagination.rb new file mode 100644 index 000000000..9220b911a --- /dev/null +++ b/lib/redmine/pagination.rb @@ -0,0 +1,300 @@ +# 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) = « + # 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) = » + # 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 + #Added by Nie guanghui + #Designed for pagination. + 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) = « + text = "\xc2\xab " + l(:label_previous) + html << '
  • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous') << '
  • ' + ' ' + end + unless paginator.previous_page + if paginator.next_page + text = "\xc2\xab " + l(:label_previous) + html << '
  • ' << yield(text, {page_param => paginator.previous_page}, :class => 'previous') << '
  • ' + ' ' + end + 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) = » + text = l(:label_next) + " \xc2\xbb" + html << '
  • ' << yield(text, {page_param => paginator.next_page}, :class => 'next') << '
  • ' + ' ' + end + + unless paginator.next_page + if paginator.previous_page + # \xc2\xbb(utf-8) = » + text = l(:label_front) + " \xc2\xbb" + html << "
  • " << yield(text, {page_param => paginator.next_page}, :class => 'next') << "
  • " + ' ' + end + 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 --git a/lib/redmine/platform.rb b/lib/redmine/platform.rb new file mode 100644 index 000000000..e06ebeeed --- /dev/null +++ b/lib/redmine/platform.rb @@ -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 --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb new file mode 100644 index 000000000..30c182d17 --- /dev/null +++ b/lib/redmine/plugin.rb @@ -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 register 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: + # * :default: default value for the plugin settings + # * :partial: path of the configuration partial view, relative to the plugin app/views directory + # Example: + # settings :default => {'foo'=>'bar'}, :partial => 'settings/settings' + # In this example, the settings partial will be found here in the plugin directory: app/views/settings/_settings.rhtml. + # + # 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 /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: + # * :class_name - one or more model(s) that provide these events (inferred from event_type by default) + # * :default - 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 (plugin/db/migrate) + 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 --git a/lib/redmine/pop3.rb b/lib/redmine/pop3.rb new file mode 100644 index 000000000..275e688de --- /dev/null +++ b/lib/redmine/pop3.rb @@ -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 --git a/lib/redmine/safe_attributes.rb b/lib/redmine/safe_attributes.rb new file mode 100644 index 000000000..c8d5852bc --- /dev/null +++ b/lib/redmine/safe_attributes.rb @@ -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 --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb new file mode 100644 index 000000000..3e51f2d4d --- /dev/null +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -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 --git a/lib/redmine/scm/adapters/bazaar_adapter.rb b/lib/redmine/scm/adapters/bazaar_adapter.rb new file mode 100644 index 000000000..8de831d6c --- /dev/null +++ b/lib/redmine/scm/adapters/bazaar_adapter.rb @@ -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 --git a/lib/redmine/scm/adapters/cvs_adapter.rb b/lib/redmine/scm/adapters/cvs_adapter.rb new file mode 100644 index 000000000..3a0d27c34 --- /dev/null +++ b/lib/redmine/scm/adapters/cvs_adapter.rb @@ -0,0 +1,462 @@ +# 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 " 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 " 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 " 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.dup, + :branch => revBranch.dup, + :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 " 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 " 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 " 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 --git a/lib/redmine/scm/adapters/darcs_adapter.rb b/lib/redmine/scm/adapters/darcs_adapter.rb new file mode 100644 index 000000000..348bd4d0f --- /dev/null +++ b/lib/redmine/scm/adapters/darcs_adapter.rb @@ -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("" + io.read + "") + 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 --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb new file mode 100644 index 000000000..2ce82b97c --- /dev/null +++ b/lib/redmine/scm/adapters/filesystem_adapter.rb @@ -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 --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb new file mode 100644 index 000000000..1876190d9 --- /dev/null +++ b/lib/redmine/scm/adapters/git_adapter.rb @@ -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 --git a/lib/redmine/scm/adapters/mercurial/hg-template-1.0.tmpl b/lib/redmine/scm/adapters/mercurial/hg-template-1.0.tmpl new file mode 100644 index 000000000..a2a324ba2 --- /dev/null +++ b/lib/redmine/scm/adapters/mercurial/hg-template-1.0.tmpl @@ -0,0 +1,12 @@ +changeset = 'This template must be used with --debug option\n' +changeset_quiet = 'This template must be used with --debug option\n' +changeset_verbose = 'This template must be used with --debug option\n' +changeset_debug = '\n{author|escape}\n{date|isodatesec}\n\n{file_mods}{file_adds}{file_dels}{file_copies}\n{desc|escape}\n\n{parents}\n\n\n' + +file_mod = '{file_mod|urlescape}\n' +file_add = '{file_add|urlescape}\n' +file_del = '{file_del|urlescape}\n' +file_copy = '{name|urlescape}\n' +parent = '{node|short}\n' +header='\n\n\n' +# footer="" diff --git a/lib/redmine/scm/adapters/mercurial/redminehelper.py b/lib/redmine/scm/adapters/mercurial/redminehelper.py new file mode 100644 index 000000000..bd82c0020 --- /dev/null +++ b/lib/redmine/scm/adapters/mercurial/redminehelper.py @@ -0,0 +1,220 @@ +# redminehelper: Redmine helper extension for Mercurial +# +# Copyright 2010 Alessio Franceschelli (alefranz.net) +# Copyright 2010-2011 Yuya Nishihara +# +# 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:: + + + + + + + + ... + + + +Output example of 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('\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('\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('\n' + % (r, _x(node.short(n)), _x(t))) + +def _manifest(ui, repo, path, rev): + ctx = repo.changectx(rev) + ui.write('\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('\n' + % _x(urllib.quote(name[:-1]))) + else: + fctx = repo.filectx(f, fileid=n) + tm, tzoffset = fctx.date() + ui.write('\n' + % (_u(name), fctx.rev(), _x(node.short(fctx.node())), + tm, fctx.size(), )) + + ui.write('\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('\n') + ui.write('\n') + ui.write('\n' % _u(repo.root)) + try: + _manifest(ui, repo, urllib.unquote_plus(path), urllib.unquote_plus(opts.get('rev'))) + finally: + ui.write('\n') + ui.write('\n') + +def rhsummary(ui, repo, **opts): + """output the summary of the repository""" + ui.write('\n') + ui.write('\n') + ui.write('\n' % _u(repo.root)) + try: + _tip(ui, repo) + _tags(ui, repo) + _branches(ui, repo) + # TODO: bookmarks in core (Mercurial>=1.8) + finally: + ui.write('\n') + ui.write('\n') + +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 --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb new file mode 100644 index 000000000..a6bf959c0 --- /dev/null +++ b/lib/redmine/scm/adapters/mercurial_adapter.rb @@ -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 '' + parse_xml("#{output}")['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 --git a/lib/redmine/scm/adapters/subversion_adapter.rb b/lib/redmine/scm/adapters/subversion_adapter.rb new file mode 100644 index 000000000..c496ba148 --- /dev/null +++ b/lib/redmine/scm/adapters/subversion_adapter.rb @@ -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 --git a/lib/redmine/scm/base.rb b/lib/redmine/scm/base.rb new file mode 100644 index 000000000..b33a9cfd1 --- /dev/null +++ b/lib/redmine/scm/base.rb @@ -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 --git a/lib/redmine/search.rb b/lib/redmine/search.rb new file mode 100644 index 000000000..dc2e526e0 --- /dev/null +++ b/lib/redmine/search.rb @@ -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 --git a/lib/redmine/subclass_factory.rb b/lib/redmine/subclass_factory.rb new file mode 100644 index 000000000..378bd39bc --- /dev/null +++ b/lib/redmine/subclass_factory.rb @@ -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 --git a/lib/redmine/syntax_highlighting.rb b/lib/redmine/syntax_highlighting.rb new file mode 100644 index 000000000..e8d9067d4 --- /dev/null +++ b/lib/redmine/syntax_highlighting.rb @@ -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. + +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(: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 --git a/lib/redmine/themes.rb b/lib/redmine/themes.rb new file mode 100644 index 000000000..eb2ba9151 --- /dev/null +++ b/lib/redmine/themes.rb @@ -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 --git a/lib/redmine/thumbnail.rb b/lib/redmine/thumbnail.rb new file mode 100644 index 000000000..96f9dfa3e --- /dev/null +++ b/lib/redmine/thumbnail.rb @@ -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 --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb new file mode 100644 index 000000000..548003220 --- /dev/null +++ b/lib/redmine/unified_diff.rb @@ -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 << '' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '' + unless offsets.last == -1 + s << CGI.escapeHTML(line[offsets.last+1..-1]) + end + s + else + CGI.escapeHTML(line) + end + end + end +end diff --git a/lib/redmine/utils.rb b/lib/redmine/utils.rb new file mode 100644 index 000000000..c289404cb --- /dev/null +++ b/lib/redmine/utils.rb @@ -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 --git a/lib/redmine/version.rb b/lib/redmine/version.rb new file mode 100644 index 000000000..a328db8af --- /dev/null +++ b/lib/redmine/version.rb @@ -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 --git a/lib/redmine/views/api_template_handler.rb b/lib/redmine/views/api_template_handler.rb new file mode 100644 index 000000000..04a7d5642 --- /dev/null +++ b/lib/redmine/views/api_template_handler.rb @@ -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 --git a/lib/redmine/views/builders.rb b/lib/redmine/views/builders.rb new file mode 100644 index 000000000..a1284fef8 --- /dev/null +++ b/lib/redmine/views/builders.rb @@ -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 --git a/lib/redmine/views/builders/json.rb b/lib/redmine/views/builders/json.rb new file mode 100644 index 000000000..feae6de53 --- /dev/null +++ b/lib/redmine/views/builders/json.rb @@ -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 --git a/lib/redmine/views/builders/structure.rb b/lib/redmine/views/builders/structure.rb new file mode 100644 index 000000000..a26154976 --- /dev/null +++ b/lib/redmine/views/builders/structure.rb @@ -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 --git a/lib/redmine/views/builders/xml.rb b/lib/redmine/views/builders/xml.rb new file mode 100644 index 000000000..8bee3fd1a --- /dev/null +++ b/lib/redmine/views/builders/xml.rb @@ -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 --git a/lib/redmine/views/labelled_form_builder.rb b/lib/redmine/views/labelled_form_builder.rb new file mode 100644 index 000000000..2bba17faf --- /dev/null +++ b/lib/redmine/views/labelled_form_builder.rb @@ -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 --git a/lib/redmine/views/my_page/block.rb b/lib/redmine/views/my_page/block.rb new file mode 100644 index 000000000..dd664acad --- /dev/null +++ b/lib/redmine/views/my_page/block.rb @@ -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 --git a/lib/redmine/views/other_formats_builder.rb b/lib/redmine/views/other_formats_builder.rb new file mode 100644 index 000000000..0093ff63a --- /dev/null +++ b/lib/redmine/views/other_formats_builder.rb @@ -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 --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb new file mode 100644 index 000000000..9a62bf6b8 --- /dev/null +++ b/lib/redmine/wiki_formatting.rb @@ -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 + ) + ((?:>)?|[^[: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 =~ /=]?/ + # 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}#{ERB::Util.html_escape content}#{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(/]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) + mail + else + %().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 --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb new file mode 100644 index 000000000..3160cd4c5 --- /dev/null +++ b/lib/redmine/wiki_formatting/macros.rb @@ -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 + "
    Error executing the #{h name} macro (#{h e.to_s})
    ".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
    {{thumbnail(image.png)}}\n{{thumbnail(image.png, size=300, title=Thumbnail)}}
    " + 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 --git a/lib/redmine/wiki_formatting/textile/formatter.rb b/lib/redmine/wiki_formatting/textile/formatter.rb new file mode 100644 index 000000000..be4bcd675 --- /dev/null +++ b/lib/redmine/wiki_formatting/textile/formatter.rb @@ -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. + # http://code.whytheluckystiff.net/redcloth/changeset/128 + def hard_break( text ) + text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1
    " ) 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
     content
    +            text.gsub!(//) do
    +              content = @pre_list[$1.to_i]
    +              if content.match(/\s?(.+)/m)
    +                content = "" +
    +                  Redmine::SyntaxHighlighting.highlight_by_language($2, $1)
    +              end
    +              content
    +            end
    +          end
    +        end
    +      end
    +    end
    +  end
    +end
    diff --git a/lib/redmine/wiki_formatting/textile/helper.rb b/lib/redmine/wiki_formatting/textile/helper.rb
    new file mode 100644
    index 000000000..28accb59f
    --- /dev/null
    +++ b/lib/redmine/wiki_formatting/textile/helper.rb
    @@ -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 --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
    new file mode 100644
    index 000000000..11ff67eef
    --- /dev/null
    +++ b/lib/tasks/ci.rake
    @@ -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 --git a/lib/tasks/ciphering.rake b/lib/tasks/ciphering.rake
    new file mode 100644
    index 000000000..520aae6f5
    --- /dev/null
    +++ b/lib/tasks/ciphering.rake
    @@ -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 --git a/lib/tasks/deprecated.rake b/lib/tasks/deprecated.rake
    new file mode 100644
    index 000000000..2e6cb3b77
    --- /dev/null
    +++ b/lib/tasks/deprecated.rake
    @@ -0,0 +1,12 @@
    +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"
    +deprecated_task "db:migrate_plugins", "redmine:plugins:migrate"
    +deprecated_task "db:migrate:plugin", "redmine:plugins:migrate"
    +deprecated_task :generate_session_store, :generate_secret_token
    diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake
    new file mode 100644
    index 000000000..934070e54
    --- /dev/null
    +++ b/lib/tasks/email.rake
    @@ -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 --git a/lib/tasks/extract_fixtures.rake b/lib/tasks/extract_fixtures.rake
    new file mode 100644
    index 000000000..65f529315
    --- /dev/null
    +++ b/lib/tasks/extract_fixtures.rake
    @@ -0,0 +1,22 @@
    +desc 'Create YAML test fixtures from data in an existing database.
    +Defaults to development database. Set RAILS_ENV to override.'
    +
    +task :extract_fixtures => :environment do
    +  sql = "SELECT * FROM %s"
    +  skip_tables = ["schema_info"]
    +  ActiveRecord::Base.establish_connection
    +  (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
    +    i = "000"
    +    File.open("#{Rails.root}/#{table_name}.yml", 'w' ) do |file|
    +      data = ActiveRecord::Base.connection.select_all(sql % table_name)
    +      file.write data.inject({}) { |hash, record|
    +        # cast extracted values
    +        ActiveRecord::Base.connection.columns(table_name).each { |col|
    +          record[col.name] = col.type_cast(record[col.name]) if record[col.name]
    +        }
    +        hash["#{table_name}_#{i.succ!}"] = record
    +        hash
    +      }.to_yaml
    +    end
    +  end
    +end
    diff --git a/lib/tasks/initializers.rake b/lib/tasks/initializers.rake
    new file mode 100644
    index 000000000..c1fdc7bf5
    --- /dev/null
    +++ b/lib/tasks/initializers.rake
    @@ -0,0 +1,24 @@
    +desc 'Generates a secret token for the application.'
    +
    +file 'config/initializers/secret_token.rb' do
    +  path = File.join(Rails.root, 'config', 'initializers', 'secret_token.rb')
    +  secret = SecureRandom.hex(40)
    +  File.open(path, 'w') do |f|
    +    f.write <<"EOF"
    +# This file was generated by 'rake generate_secret_token', 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.
    +RedmineApp::Application.config.secret_token = '#{secret}'
    +EOF
    +  end
    +end
    +
    +desc 'Generates a secret token for the application.'
    +task :generate_secret_token => ['config/initializers/secret_token.rb']
    diff --git a/lib/tasks/jdbc.rake b/lib/tasks/jdbc.rake
    new file mode 100644
    index 000000000..289b3d94c
    --- /dev/null
    +++ b/lib/tasks/jdbc.rake
    @@ -0,0 +1,8 @@
    +# This file was generated by the "jdbc" generator, which is provided
    +# by the activerecord-jdbc-adapter gem.
    +#
    +# This file allows you to use Rails' various db:* tasks with JDBC.
    +if defined?(JRUBY_VERSION)
    +  require 'jdbc_adapter'
    +  require 'jdbc_adapter/rake_tasks'
    +end
    diff --git a/lib/tasks/load_default_data.rake b/lib/tasks/load_default_data.rake
    new file mode 100644
    index 000000000..cc6774bce
    --- /dev/null
    +++ b/lib/tasks/load_default_data.rake
    @@ -0,0 +1,35 @@
    +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.message
    +    rescue => error
    +      puts "Error: " + error.message
    +      puts "Default configuration data was not loaded."
    +    end
    +  end
    +end
    diff --git a/lib/tasks/locales.rake b/lib/tasks/locales.rake
    new file mode 100644
    index 000000000..6311d6ab1
    --- /dev/null
    +++ b/lib/tasks/locales.rake
    @@ -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 --git a/lib/tasks/metrics.rake b/lib/tasks/metrics.rake
    new file mode 100644
    index 000000000..214cc996e
    --- /dev/null
    +++ b/lib/tasks/metrics.rake
    @@ -0,0 +1,6 @@
    +begin
    +  require 'metric_fu'
    +rescue LoadError
    +  # Metric-fu not installed
    +  # http://metric-fu.rubyforge.org/
    +end
    diff --git a/lib/tasks/migrate_from_mantis.rake b/lib/tasks/migrate_from_mantis.rake
    new file mode 100644
    index 000000000..465ca9958
    --- /dev/null
    +++ b/lib/tasks/migrate_from_mantis.rake
    @@ -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 --git a/lib/tasks/migrate_from_trac.rake b/lib/tasks/migrate_from_trac.rake
    new file mode 100644
    index 000000000..923b0c620
    --- /dev/null
    +++ b/lib/tasks/migrate_from_trac.rake
    @@ -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 = '
    '
    +          else
    +            m_sl = shebang_re.match(line)
    +            if m_sl
    +              shebang_line = true
    +              line = ''
    +            end
    +            m_pre_end = pre_end_re.match(line)
    +            if m_pre_end
    +              line = '
    ' + if shebang_line + line = '' + 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 --git a/lib/tasks/permissions.rake b/lib/tasks/permissions.rake new file mode 100644 index 000000000..02ce1b2a8 --- /dev/null +++ b/lib/tasks/permissions.rake @@ -0,0 +1,9 @@ +namespace :redmine do + desc "List all permissions and the actions registered with them" + task :permissions => :environment do + puts "Permission Name - controller/action pairs" + Redmine::AccessControl.permissions.sort {|a,b| a.name.to_s <=> b.name.to_s }.each do |permission| + puts ":#{permission.name} - #{permission.actions.join(', ')}" + end + end +end diff --git a/lib/tasks/redmine.rake b/lib/tasks/redmine.rake new file mode 100644 index 000000000..0ad4f2f1a --- /dev/null +++ b/lib/tasks/redmine.rake @@ -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 --git a/lib/tasks/reminder.rake b/lib/tasks/reminder.rake new file mode 100644 index 000000000..67661a361 --- /dev/null +++ b/lib/tasks/reminder.rake @@ -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 --git a/lib/tasks/testing.rake b/lib/tasks/testing.rake new file mode 100644 index 000000000..cfb8e77f9 --- /dev/null +++ b/lib/tasks/testing.rake @@ -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 --git a/lib/tasks/yardoc.rake b/lib/tasks/yardoc.rake new file mode 100644 index 000000000..aa6c5eeb0 --- /dev/null +++ b/lib/tasks/yardoc.rake @@ -0,0 +1,21 @@ +begin + require 'yard' + + YARD::Rake::YardocTask.new do |t| + files = ['lib/**/*.rb', 'app/**/*.rb'] + files << Dir['vendor/plugins/**/*.rb'].reject {|f| f.match(/test/) } # Exclude test files + t.files = files + + static_files = ['doc/CHANGELOG', + 'doc/COPYING', + 'doc/INSTALL', + 'doc/RUNNING_TESTS', + 'doc/UPGRADING'].join(',') + + t.options += ['--output-dir', './doc/app', '--files', static_files] + end + +rescue LoadError + # yard not installed (gem install yard) + # http://yardoc.org +end diff --git a/plugins/README b/plugins/README new file mode 100644 index 000000000..edef25679 --- /dev/null +++ b/plugins/README @@ -0,0 +1 @@ +Put your Redmine plugins here. diff --git a/public/404.html b/public/404.html new file mode 100644 index 000000000..23c08dd81 --- /dev/null +++ b/public/404.html @@ -0,0 +1,23 @@ + + +Redmine 404 error + + +

    Page not found

    +

    The page you were trying to access doesn't exist or has been removed.

    +

    Back

    + + diff --git a/public/500.html b/public/500.html new file mode 100644 index 000000000..588d83bb6 --- /dev/null +++ b/public/500.html @@ -0,0 +1,25 @@ + + +Redmine 500 error + + +

    Internal error

    +

    An error occurred on the page you were trying to access.
    + If you continue to experience problems please contact your Redmine administrator for assistance.

    +

    If you are the Redmine administrator, check your log files for details about the error.

    +

    Back

    + + diff --git a/public/application.css b/public/application.css new file mode 100644 index 000000000..deb7b3217 --- /dev/null +++ b/public/application.css @@ -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: #000; height:1.8em; font-size: 1.0em; 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: #000000; 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: #039ea0; + 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 --git a/public/dispatch.fcgi.example b/public/dispatch.fcgi.example new file mode 100644 index 000000000..85184c446 --- /dev/null +++ b/public/dispatch.fcgi.example @@ -0,0 +1,20 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../config/boot' +require File.dirname(__FILE__) + '/../config/environment' + +class Rack::PathInfoRewriter + def initialize(app) + @app = app + end + + def call(env) + env.delete('SCRIPT_NAME') + parts = env['REQUEST_URI'].split('?') + env['PATH_INFO'] = parts[0] + env['QUERY_STRING'] = parts[1].to_s + @app.call(env) + end +end + +Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(RedmineApp::Application) diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..75a4c3dfd46656c981907ac9d82ddce23c622d7f GIT binary patch literal 10415 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 literal 0 HcmV?d00001 diff --git a/public/help/wiki_syntax.html b/public/help/wiki_syntax.html new file mode 100644 index 000000000..a92720b4d --- /dev/null +++ b/public/help/wiki_syntax.html @@ -0,0 +1,66 @@ + + + + + +Wiki formatting + + + + +

    Wiki Syntax Quick Reference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Font Styles
    Strong*Strong*Strong
    Italic_Italic_Italic
    Underline+Underline+Underline
    Deleted-Deleted-Deleted
    ??Quote??Quote
    Inline Code@Inline Code@Inline Code
    Preformatted text<pre>
     lines
     of code
    </pre>
    +
    + lines
    + of code
    +
    +
    Lists
    Unordered list* Item 1
    * Item 2
    • Item 1
    • Item 2
    Ordered list# Item 1
    # Item 2
    1. Item 1
    2. Item 2
    Headings
    Heading 1h1. Title 1

    Title 1

    Heading 2h2. Title 2

    Title 2

    Heading 3h3. Title 3

    Title 3

    Links
    http://foo.barhttp://foo.bar
    "Foo":http://foo.barFoo
    Redmine links
    Link to a Wiki page[[Wiki page]]Wiki page
    Issue #12Issue #12
    Revision r43Revision r43
    commit:f30e13e43f30e13e4
    source:some/filesource:some/file
    Inline images
    Image!image_url!
    !attached_image!
    + +

    More Information

    + + + diff --git a/public/help/wiki_syntax_detailed.html b/public/help/wiki_syntax_detailed.html new file mode 100644 index 000000000..0398e4fa0 --- /dev/null +++ b/public/help/wiki_syntax_detailed.html @@ -0,0 +1,281 @@ + + + +RedmineWikiFormatting + + + + + +

    Wiki formatting

    + +

    Links

    + +

    Redmine links

    + +

    Redmine allows hyperlinking between resources (issues, changesets, wiki pages...) from anywhere wiki formatting is used.

    +
      +
    • Link to an issue: #124 (displays #124, link is striked-through if the issue is closed)
    • +
    • Link to an issue note: #124-6, or #124#note-6
    • +
    + +

    Wiki links:

    + +
      +
    • [[Guide]] displays a link to the page named 'Guide': Guide
    • +
    • [[Guide#further-reading]] takes you to the anchor "further-reading". Headings get automatically assigned anchors so that you can refer to them: Guide
    • +
    • [[Guide|User manual]] displays a link to the same page but with a different text: User manual
    • +
    + +

    You can also link to pages of an other project wiki:

    + +
      +
    • [[sandbox:some page]] displays a link to the page named 'Some page' of the Sandbox wiki
    • +
    • [[sandbox:]] displays a link to the Sandbox wiki main page
    • +
    + +

    Wiki links are displayed in red if the page doesn't exist yet, eg: Nonexistent page.

    + +

    Links to other resources:

    + +
      +
    • Documents: +
        +
      • document#17 (link to document with id 17)
      • +
      • document:Greetings (link to the document with title "Greetings")
      • +
      • document:"Some document" (double quotes can be used when document title contains spaces)
      • +
      • sandbox:document:"Some document" (link to a document with title "Some document" in other project "sandbox")
      • +
    • +
    + +
      +
    • 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"
      • +
      • sandbox:version:1.0.0 (link to version "1.0.0" in the project "sandbox")
      • +
    • +
    + +
      +
    • Attachments: +
        +
      • attachment:file.zip (link to the attachment of the current object named file.zip)
      • +
      • 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)
      • +
    • +
    + +
      +
    • Changesets: +
        +
      • r758 (link to a changeset)
      • +
      • commit:c6f4d0fd (link to a changeset with a non-numeric hash)
      • +
      • svn1|r758 (link to a changeset of a specific repository, for projects with multiple repositories)
      • +
      • commit:hg|c6f4d0fd (link to a changeset with a non-numeric hash of a specific repository)
      • +
      • sandbox:r758 (link to a changeset of another project)
      • +
      • sandbox:commit:c6f4d0fd (link to a changeset with a non-numeric hash of another project)
      • +
    • +
    + +
      +
    • Repository 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)
      • +
      • source:"some file@52#L120" (use double quotes when the URL contains spaces
      • +
      • export:some/file (force the download of the file)
      • +
      • source:svn1|some/file (link to a file of a specific repository, for projects with multiple repositories)
      • +
      • sandbox:source:some/file (link to the file located at /some/file in the repository of the project "sandbox")
      • +
      • sandbox:export:some/file (force the download of the file)
      • +
    • +
    + +
      +
    • Forum messages: +
        +
      • message#1218 (link to message with id 1218)
      • +
    • +
    + +
      +
    • Projects: +
        +
      • project#3 (link to project with id 3)
      • +
      • project:someproject (link to project named "someproject")
      • +
    • +
    + + +

    Escaping:

    + +
      +
    • You can prevent Redmine links from being parsed by preceding them with an exclamation mark: !
    • +
    + + +

    External links

    + +

    HTTP URLs and email addresses are automatically turned into clickable links:

    + +
    +http://www.redmine.org, someone@foo.bar
    +
    + +

    displays: http://www.redmine.org,

    + +

    If you want to display a specific text instead of the URL, you can use the standard textile syntax:

    + +
    +"Redmine web site":http://www.redmine.org
    +
    + +

    displays: Redmine web site

    + + +

    Text formatting

    + + +

    For things such as headlines, bold, tables, lists, Redmine supports Textile syntax. See http://en.wikipedia.org/wiki/Textile_(markup_language) for information on using any of these features. A few samples are included below, but the engine is capable of much more of that.

    + +

    Font style

    + +
    +* *bold*
    +* _italic_
    +* _*bold italic*_
    +* +underline+
    +* -strike-through-
    +
    + +

    Display:

    + +
      +
    • bold
    • +
    • italic
    • +
    • *bold italic*
    • +
    • underline
    • +
    • strike-through
    • +
    + +

    Inline images

    + +
      +
    • !image_url! displays an image located at image_url (textile syntax)
    • +
    • !>image_url! right floating image
    • +
    • If you have an image attached to your wiki page, it can be displayed inline using its filename: !attached_image.png!
    • +
    + +

    Headings

    + +
    +h1. Heading
    +h2. Subheading
    +h3. Subsubheading
    +
    + +

    Redmine assigns an anchor to each of those headings thus you can link to them with "#Heading", "#Subheading" and so forth.

    + + +

    Paragraphs

    + +
    +p>. right aligned
    +p=. centered
    +
    + +

    This is a centered paragraph.

    + + +

    Blockquotes

    + +

    Start the paragraph with bq.

    + +
    +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.
    +
    + +

    Display:

    + +
    +

    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.

    +
    + + +

    Table of content

    + +
    +{{toc}} => left aligned toc
    +{{>toc}} => right aligned toc
    +
    + +

    Macros

    + +

    Redmine has the following builtin macros:

    + +

    hello_world

    Sample macro.

    include

    Include a wiki page. Example:

    + +
    {{include(Foo)}}
    macro_list

    Displays a list of all available macros, including description if available.

    + + +

    Code highlighting

    + +

    Default code highlightment relies on CodeRay, 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.

    + +

    You can highlight code in your wiki page using this syntax:

    + +
    +<pre><code class="ruby">
    +  Place you code here.
    +</code></pre>
    +
    + +

    Example:

    + +
     1 # The Greeter class
    + 2 class Greeter
    + 3   def initialize(name)
    + 4     @name = name.capitalize
    + 5   end
    + 6 
    + 7   def salute
    + 8     puts "Hello #{@name}!" 
    + 9   end
    +10 end
    +
    + + diff --git a/public/htaccess.fcgi.example b/public/htaccess.fcgi.example new file mode 100644 index 000000000..f06975d43 --- /dev/null +++ b/public/htaccess.fcgi.example @@ -0,0 +1,49 @@ +# General Apache options + + AddHandler fastcgi-script .fcgi + + + AddHandler fcgid-script .fcgi + +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 + + RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] + + + RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] + + +# 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 "

    Application error

    Rails application failed to start properly" diff --git a/public/images/115960_50.jpg b/public/images/115960_50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa45853f50ae3b601f55d37667340c4c08dc8af0 GIT binary patch literal 1570 zcmbW!c{tR090%~<9Lx+OhH;O^*$62^B8@X-(zd41&SEnvtTjEOT;te{oUMvnO$bHE zk#bDMt{7)>jAIx!#(lJw80A>AqxRW-p8acg-=F9E{pb66KF{a%d<8>-aX^Y_=U@kb zzyJUe79bb_Yyh~ZC`?oY4uioE2)Gy$ErAplM=DCoNTOAguzOXMFc?)$eVnSgo(2Y^ zePqAhAp;{LBP`C8V1hrUZ)k+y9Rfli5J+*Pf`o(uUJav$|IZOL04O+s2k;P(Isit2 zASjT41z?4Hihw=^_%k3d1S%p5gCoSmg$>nG02l;;fT0i(5hzsH9U*)NpePY(H3KVA z87EJeIt`7#mYfIIu&#V1OX^+LG^7MXA;je56%>`U_TjYm>lht2K4M~e)aJOYo&5<1 z;+eC~F0SXkB70r9c*)zx_uDI11A~G?Lg~@hV`Agt6B1MIq^6~3WZq@uKX_PB_^7D3 zY7^S^B0Xxtmc;1w)PHoU;n@$XK0wqo0y!Mo|&DSUs!p+y2fAs@Nr{v*98I~ zpIO5DGwdHOl+Xo+LLpGtt_uVX79I!+Dxzi}DsANi^Q6hB~9wrKte#m&x4=<3t)Czi|0c@>zFb*{Q^LNtXxkt zMNd1lzNsqIv{%wyPT2BUgS=VSVY6rm(yy+r_=H^p|iraKGo9M>+y}%_^ zhwb-JW_mHrT#f@JIhG={9?TU+QMkW%8H*CavQ#|8T|q7b1JqamGQDTFRPYlrf9j#&7b&NbJjN zaY+Yr-;*tg<$T<&ypmdD_K2Rp&abN=)!=R0z_-RdugeSb7o48Pdaa`F@bjNMv-RwV zP92CDssbui_t_J4l7`<*-6v}o7d#nb`OkGcO$cwm%1tWA(grK$=kmM8#4HB)jIFT~ obuN(b{2l$$hH-c+HiN0h4yS$p8QV literal 0 HcmV?d00001 diff --git a/public/images/121944_50.jpg b/public/images/121944_50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..26e7db3e7cbb4c2ef68bf5691c9777ab1f36f22c GIT binary patch literal 1306 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!}m3zzW#yRE}5L}b^7=%`atX5{mZYdPuelR z^V|FKhpVd{j=0)B$=0)85tdVzrLlKws_L0HmB%)Jj6O1J_5N?JJGX2(dFvpvrQDN` zKf`>dAK5Q)!+T$J``qGbk&9UB=4#hTC23*(Oxv+H+2u zoIZBHV|&}*%4_6&6}_aFwVq(t@Hry0^J~?heK0^;f71w85xzO;i32!UeXE6SI=W+fSZ>eD1 zObMQ^>sG`npIUQe$(#JYo4Q(ar>w9(uGDqmz=5m(Y_^}9h--*7zRZPUXd{|)lj7XAoc%b_~y>V2-Y^AGg@XNWDE zr?lHDZ?4{AGo{X8K{xSym7*J8j}?Ahml@bS_1ua_DvM85`uDF7vlo+CbN_VTHIXiR z-Hlt4?XRuOyk~eNmqTd7T=(xk>}RauzI{^v{qo&2H><3R-7nQ#X1Vrf=$hhf=UwCl z?E+_KTGgNT|F>22`Rul{R8EsGE4$P3>I~1NdCVG0On&W)c^nh literal 0 HcmV?d00001 diff --git a/public/images/12_50.png b/public/images/12_50.png new file mode 100644 index 0000000000000000000000000000000000000000..af618c6974b46d373509303c71a488986df55b18 GIT binary patch literal 5867 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 literal 0 HcmV?d00001 diff --git a/public/images/1downarrow.png b/public/images/1downarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d07e92b2602e9498d6d62a2dfb8bc2deaf69f1 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}V1Q4E>wgA@d+*QPdw*@tx$HT| zil2YKxAY#6y!QP4z4zbWuYF#9@B6X;|Nmcmer(RM>i_@0Z++gg^jOc7y~W?ZzkmPz z`PTO>Ywz`}z1Fkz98kPv&fb>X56UxuhBKA~`2{mLJiCzw zAS^z8!W5xKt`EhW8#Wska&U1To>EX$`1!+!PlZY*8#iq<-c+CwgA@@BiQLeLrXK^Eq4Z z&DnZw&f0TxzJGte^m+Ey=RMcnAG`Ma*wSMyEo+nCe}BIAdG+(}*Z%+ifA9UZIeUTZ zdrR*X&pB2+=Unl*=X<>iT6%%TGL{7S1v5B2yO9Ru*n7G-hDcmaPFSEmVS>Zc;?C|u z<gTe~DWM4fP8wyl literal 0 HcmV?d00001 diff --git a/public/images/233683_50.jpg b/public/images/233683_50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..65ef363cc478f197001e112fcf158f01d4272b41 GIT binary patch literal 1446 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!_(Xvvt_JP^FpWWyC?EodgGkB(50-qGtG?! z%alX58;PgioWSv*YJS$U5?k%ST|3hvQ`(;hv9rv*`7+@3cB9-*&k3a`($4>Uay{2- zy6?Jn(I~Mg!FOjB|Je4)_tc~fPStZ}N= zSzEW8f8%`9?|u2~(zlCZWP`2=-9M=I_wc9SV1wTj_4e+7WPFP^Vdao;mZ|xCWhsS<*AqcU)GzEv&u7 zz-3)aa}x(cUtvsG=c*SQS4H{jEzK`@aKfjEq5qxz`K;+jr2h8J%u>GWvfVi|ZDQNQ zljqfCuCJDw_~g#dUt3n4+Po<}BfsQB;d95IUD}8Ewyw6+QM)BQfnDN{#>!u3ynnUq zo+TB0Kl)Dn;uw|`#VLkQs{5C!Enn*^^8EB&Jx^mxKX0jXm)Bj&Oq~=IEML$wr#53( z`i>LcQ}r+BS^d>Mv-0%$)Qzu$pFIt~^J2@%=>Z$HwIBKT>TBvs*547#adRVY&>~<^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!}njD3@Nj;tz)-k@0EHcx+B9}@$`!4a#NPv z3U}`EU2;Y?`;lJnlFjat**m8^==c%%WB$uXF?;cno9kS{rxiu7w6WUu!EQ0r4%vLC z-^RR~jMrPw=$m@xuG_|ix6fbOS@|kH_(F-sZD0SDx$hKrZ|{4=Ddw?6dg_!XfMeCRsoa9+9Tb2BEU3SbgPt!{G*@bp9KDw7H z=Sqim99sFuFmh+SOFmawmd_D`Y1?kvT(%ZHcv!&R>&X7gim|qrOc}Se-Es4K^Z8fU z)O$-sbe}3O-td^yGiPnlnv~exyThz(1+S{-My~zfb@t!I)$!Xom>l*!x3s_fd3~Jc z<4K-^5@J0Khc8T=^~6ScN#?Hjb|KRp8YyLy93uE<%>Tf&c}<>Q|07xNw`!5P>P1PD zB)Lmo?nvHO^*4Kwrb?mjXU}=0Xjd>=TbUE~qNf z$5wUaSnkEQMustrJ#!LD)~w$;cgZAsJFRI8SIy8#pJvA78fRhaFM4ElwRGImxk0b} z_>^{PUFUOJcJ*{q1-tF4zQrq}GsJH0c$Q@6;rMg*{TtQSxeKc`(kATu?45siUh(V5 z>*m5S=RV)@y5#j-=UkC*i5sVAtxmqYM7D5D`|rRmg`0v3Kiz*^FI@Da?|yh}OUqoh z$l`=V{-b$R-YpvFdl)Y`lU}a+B5EO!$!NAGI&BMdX$BD3qm5rT|g#+1UMrIZ! gRJSlPF;EWx0C@!ixOR{4IsgCw07*qoM6N<$f_;31qyPW_ literal 0 HcmV?d00001 diff --git a/public/images/2uparrow.png b/public/images/2uparrow.png new file mode 100644 index 0000000000000000000000000000000000000000..352cc2bb9df4effcb007b0cce3cd459ff6b0817a GIT binary patch literal 292 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 Pr4}(|XdALy1b65U&HTR# literal 0 HcmV?d00001 diff --git a/public/images/926055_50.jpg b/public/images/926055_50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..90e0e84745921f6ce5380b5459a2333435e2053e GIT binary patch literal 1336 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!}GhwA#)8)GxmFV=>AJKR;+)w&cd`$s%O>t zNorG9xy`AZX*+kzx)rb5GnAj%@SoeuYI@c*N3r#t`;3MZR(1KQm4EcVb>CRLV}hgb zj<5;;88}wH%Tt=D0>!UiLcu-d6wUu6?st{Sb`#E$1cko zv3HB1GwYK?o9?M6IREfiXw}bu9Qk;|#-*7D?@B$`Xtc88Y~;)%JQuz1b$#x4=uw|> zu)6$L$ms%y--~70s<^rrrCX@?A6k9liQsvry)~@%>Hf1<+nfp6`8=;$I7|s2N{km!S z%sZ@Uw}r|=-^N6?d=y?QRr2(-?CsZ2dOvJ=xx&&jcBYxwhd43Dlati6UKCDE@Mj56 z7Tr_yvUqWGGqY8-)#v#q1bjH8999hU=!q8yHAC$n<<&zqIRVZ@=g*zh_gXy;-MR!1cK8O}*BeKfKE# zw#_d{+1h$Hx~+ue%iCFxe14>CXV>w2xAoo+-EX(O7>-pc?Jz96@M>Z4`mNE&FY4=< zoX!Y76C~xX7$`3DfY0;zHrv-Hq&)3zsuY=d8OERP`j*T0gl%X4Ro;rVpDU}bKKjpa zIqhHR;fPmDPFt^7buU%)TuxES9J$)8x7&Xm|Ibj?rTy~aqti(hp61&l--OH0tx|9P z&+v5pr7rE$$MS`@wFj@e*#9f${<~S9bmRZIN#FnVDr3>k>=Lu3J5FgV+IjZ;|C<1R Ca5O0Z literal 0 HcmV?d00001 diff --git a/public/images/add.png b/public/images/add.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d26db7c071da62daed91569d69ed280969707b GIT binary patch literal 680 zcmV;Z0$2TsP)r0bi7>E5^wl4*Pq=s22s3|2_C~w(pii%F#mUC;0&h~CDox05fEu9k&6}6$;Xrwzh z55ogy;?&Yb>g!OVjUotY!>_;I6-`IWh#vTTdEmO9=f1h`BmhbOlix0M({;=akA!S> ziKylYL0JBxI^6KQf|6RxNYQ99^F)DeT1vD}N(xAl0q)`4zcD-3=e`utjSZ??dFU?1+Ft(-FYv@mRG(DYIW@q7h%)*EqPGx?D}b1|`F!X3-4C>%^yo@T@iQu(6-qGaf5q|s3cCoM7h z+Ck1#K|WOp<7yimG%U1mz*ey$G)yEMWzIk@K^SsE`2(5gSs-D4ZGd^h0FAd1SzRen zICLCNxJ=jdnatdtbTYg1B9);@38%H64WDm4L!DEx$YkXy=3lq*U-KP7M#~=nDAU0J O0000&XcX%#MzZjBIX>jsn399tK7Vj0`*n7&^N|3yOit7(8A5 KT-G@yGywoioE?|| literal 0 HcmV?d00001 diff --git a/public/images/arrow_expanded.png b/public/images/arrow_expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1c563bf8d6a1c9789cbf31e27cce20c73ee9b8 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6QaoK8Lp07O|2f|vZ@{O?%Kra< z(vOoLnjcypHgC(n&%M(?d&v%kP%Q`Dp1PvwtYmgC(yfrY^*(}c07*ahSe22WQ%mvv4F FO#p@2KFI(8 literal 0 HcmV?d00001 diff --git a/public/images/attachment.png b/public/images/attachment.png new file mode 100644 index 0000000000000000000000000000000000000000..3762eafec7ef7f6b8d753b5033a6f53f1a195c59 GIT binary patch literal 939 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^D_f|8SytE;QGZryt9 z*s*ix&Rx59?cTk6{}~wmkAl$<815lp;FK#1%o3a>L4Lt7zcK{-R|o+G13g_FLnJQu zo_FLrV8G#WvCxO@ef^_t7nfu%3@HDv*wk_TfwYGm!=z&7j(g?}0@v~+-frT&n!!42 y?N-5_SB!722bDElS!b3Z@EoMmjD$F{7MyK@=Pa0X9TKbLh*2~7Zn9x_7! literal 0 HcmV?d00001 diff --git a/public/images/avatars/AnonymousUser/0 b/public/images/avatars/AnonymousUser/0 new file mode 100644 index 0000000000000000000000000000000000000000..26e7db3e7cbb4c2ef68bf5691c9777ab1f36f22c GIT binary patch literal 1306 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!}m3zzW#yRE}5L}b^7=%`atX5{mZYdPuelR z^V|FKhpVd{j=0)B$=0)85tdVzrLlKws_L0HmB%)Jj6O1J_5N?JJGX2(dFvpvrQDN` zKf`>dAK5Q)!+T$J``qGbk&9UB=4#hTC23*(Oxv+H+2u zoIZBHV|&}*%4_6&6}_aFwVq(t@Hry0^J~?heK0^;f71w85xzO;i32!UeXE6SI=W+fSZ>eD1 zObMQ^>sG`npIUQe$(#JYo4Q(ar>w9(uGDqmz=5m(Y_^}9h--*7zRZPUXd{|)lj7XAoc%b_~y>V2-Y^AGg@XNWDE zr?lHDZ?4{AGo{X8K{xSym7*J8j}?Ahml@bS_1ua_DvM85`uDF7vlo+CbN_VTHIXiR z-Hlt4?XRuOyk~eNmqTd7T=(xk>}RauzI{^v{qo&2H><3R-7nQ#X1Vrf=$hhf=UwCl z?E+_KTGgNT|F>22`Rul{R8EsGE4$P3>I~1NdCVG0On&W)c^nh literal 0 HcmV?d00001 diff --git a/public/images/avatars/Project/0 b/public/images/avatars/Project/0 new file mode 100644 index 0000000000000000000000000000000000000000..beea149043ce3aab9d254b7e11fb68d55e160b76 GIT binary patch literal 1598 zcmbW!c{tR090%~<9OiIr4I{V73?YP}91)UZrZqC!v?j!)95I{w%DE*Z$2dwggq&d` zBS#NHiXIjTk{DSTNonc*@`n`nV^wj|(n>nY zsv4Tw+S(XJJwsi*!67Ye{O%AC5{VQP5EK^@635F)%i;fXxJ>{G0pI~V1cU{^C=dh% z;Pp!QcoazW}eHdM^M5K_Fl#gpUsj<#k`>y#r7bpRk;!2~5Ps z8IHYz#z&<*K;Vu)ZWbl?EXixR_(UW5_lb#1NGcpqR8l^uefWruuAaW>2{UsGO9IjM z^iOB(&i-sqz2JKBlAF7Sub+QFU{G*K%&*t3$KHsGPo<}&XJp>Kla-s7|FEF2sJNuE z>Pa=T=4ox+^On}O7ws=!b@cYV>3=&gIK-M@Prjd;o|*kHx4g2t###TovAMPD0s)Zk zEZ+Sc_74||=K@2a5GZ`t1p){14g>||lhcF=o7ljeuZUprQ3&+$ln0NSkvJ{#lBkPM z5C1-S?FohDUD`L!Y!Jrc1|F5 ze$ml^pO{}gxP7lrMpaFvh3(zB(?vVELCCYeKhS3t6jA?KY;A^9He>*r2v&P-G_<#< zeT-}xetx>{+;se!sFK2kq*R8HsGct|Z~N1xtiq&qEZI$i3%I#k%QF*_Gzpu@Tg$Ac z*m*hi1NxE1^PGy}`z{QfIA)!Gy6b#$$iVA5PK>*K|5OaPK;kxaxX36&B|(H>GIkVm zl1`n8ODMEsJA~axFAqqp>JXC_YL7A_=hl{ohFyObdww;{jOt;&9^3;!lhF)ojO|z0 zv%)qq$XB!>iBm) zec_`N$z7q6Y}WR~cayRmP0|l2XA-E_bUNk|=GwtonWqRxjp^pSB@0U8!tipH!l80U z3Pb(v^xU?qXko>U5!*Kl!}8*Qq#0uSh_70C=x$318ylyGpQAUmSIj#RHppN6F#;b};~_#nnRMxk)}>DE2S_?PBv;jT(U9CO2p=A zTH5CDtI?I;a7me|!CeQLx4#N4y-eL=>A7@x>j+!Ojc3;(WrDg?beikZj^TQ|Cu+3q9Gp!e)lVXGV*M3e)U-RL){)y zj2Fc}u%aMiyDN8$tx|e+!R2xr7EU(DBf3L27u)o2vToIsR65WqQzt`iMv6y8T9m^v zvAq=@*(m?g`d}|Lc?!ki;!3M$ERrE+cwLuWE8#7ZiyANa#Zu8=>+9ie$GR+n>J6TrsW=_d)GF#`{l;xyBhXb9yJU4B!zaa z=OgVgC0Er9Gt}BUwUX!t{)UZ`N(D@;lh_FUh%1xsiQ1krz?7YF@i8Z9^~Nh3CgPSg Pr4}(|XdALy1b65U&HTR# literal 0 HcmV?d00001 diff --git a/public/images/avatars/Project/6314 b/public/images/avatars/Project/6314 new file mode 100644 index 0000000000000000000000000000000000000000..6c099118c4ebaa99d9db7e1204dc0d17073ff926 GIT binary patch literal 36513 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

    (E5d4@$h@n444z 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 literal 0 HcmV?d00001 diff --git a/public/images/avatars/User/1 b/public/images/avatars/User/1 new file mode 100644 index 0000000000000000000000000000000000000000..fa4fd4110616804c956a8fe4c388700ec4408eef GIT binary patch literal 775702 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

    _kkug=-( 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

    iN8w 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